1

So I found a way to wrap console.log so that when called through the wrapper it preserves the file/line number from where it was called.

But I'd like to know how I could wrap it once more (perhaps several times if the actual logging happened to be in a very deep level).

class Debugger {
  _log() {
    return Function.prototype.bind.call(console.log, console);
  }

  log = this._log();

  specialLog(msg: string) {
    this.log('special: ' + msg);
  }
}

const debug = new Debugger();
debug.log('hi'); // works perfect: correct file/line number
debug.specialLog('hi'); // line number -> where this.log() is called.

From this sample code, how should I modify specialLog so that it works as log?
I've tried several combinations with .bind, .apply, .call trying to pass the console context through, but no success.

update:

specialLog(msg: string) {
  return this.log.bind(console, 'special ' + msg);
}

debug.specialLog('hi')(); // correct, but notice the extra '()'

This is the closest I could get, but is there a way to do it without having to execute it after call?

update 2: jsfiddle
https://jsfiddle.net/mqa1duvr/

update 3: reason I need it to go through another wrapper:
The actual debugger looks something like this:

class Debugger {
  debug(...)
  trace(...)
  // and inside each these debug..trace..warn etc..
  // there are set colors, timestamps, send log to server etc..
  // then, finally after all the filters, there's the "final" log.
  _log(...)
}

If I can make it go through several functions deep while having the caller's context, then I could keep the functions small.

user7552
  • 315
  • 1
  • 3
  • 19

1 Answers1

2

You can set default arguments (the string "special: ") using bind. So this should work:

specialLog =  Function.prototype.bind.call(console.log, console, "Special: ");
//                                                             ^^^^^^^^^^^^^^

Explanation:

When specialLog get called, the first argument passed to console.log will always be "Special: ", so if you call it like:

specialLog("Hello, world!");

it will be as if you call console.log like:

console.log("Special: ", "Hello, world!");

which prints the string: "Special: Hello, world!", your desired result.

user7552 (op) edit:
for my case, it would be:

specialLog =  Function.prototype.bind.call(this.log, console, "Special:");

using this.log (reference inside the debugger class), instead of console.log.

user7552
  • 315
  • 1
  • 3
  • 19
ibrahim mahrir
  • 31,174
  • 5
  • 48
  • 73