3

Using PhantomJS 1.9.x, I wanted to use console.log.bind(console) in my code, but it throws an error due to console.log.bind being undefined (same for console.error.bind(console) etc.)

It is a known issue with PhantomJS 1.x that it does not support Function.prototype.bind.

However even after including a bind polyfill things are not working as expected:

 console.log(Function.prototype.bind);
 // function bind(obj) { ... }
 console.log(console.log.bind);
 // undefined

How can I fix that issue?

jakub.g
  • 38,512
  • 12
  • 92
  • 130
  • Related: [How to safely wrap `console.log`?](http://stackoverflow.com/q/8785624/1048572) and [console.log.apply not working in IE9](http://stackoverflow.com/q/5538972/1048572) – Bergi Dec 02 '15 at 15:25

1 Answers1

3

It seems that in PhantomJS, console is a bit special in that it is not an instance of Function (contrary to Chrome or Firefox). Hence extending Function.prototype has no action on it.

console.log(typeof console.log === "function");
// true
console.log(console.log instanceof Function);
// false

(probably the console.log comes from a different JavaScript context, and the issue here is the same as with myArray instanceof Array evaluating to false when myArray comes from an iframe).

To fix the issue, apart from including a polyfill for Function.prototype.bind, you could assign bind to console methods manually, like this:

if (!console.log.bind) {
    // PhantomJS quirk
    console.log.constructor.prototype.bind = Function.prototype.bind;
}

After this, all console methods will have .bind():

console.log(console.log.bind);   // function bind(obj) { ... }
console.log(console.info.bind);  // function bind(obj) { ... }
console.log(console.debug.bind); // function bind(obj) { ... }
console.log(console.warn.bind);  // function bind(obj) { ... }
console.log(console.error.bind); // function bind(obj) { ... }
jakub.g
  • 38,512
  • 12
  • 92
  • 130
  • 1
    What's `Object.getPrototypeOf(console.log)` then? Maybe `console.log.__proto__ = Function.prototype` is more appropriate than what you are doing. – Bergi Dec 02 '15 at 15:27
  • `console.log(Object.getPrototypeOf(console.log).toString());` prints `'function () { [native code] }'`. Yes changing `__proto__` is another option, though then I'd have to change it per each `console` function, and I don't know if it won't have unexpected side issues. – jakub.g Dec 02 '15 at 15:39