简体   繁体   中英

javascript assign console.log to an object

I'm using sinon.js for testing, but it's not relevant here. Original sinon implementation contains following code:

sinon = {
  log: function() {}
  //...
}

there is just a stub log function to be overriden by users, higher-level sinon functions use that. That makes sense. And now I try to define sinon.log function for myself:

sinon.log = console.log;

When I try to log something, I get a nasty error I don;t clearly understand:

sinon.log(1)
> TypeError: Illegal invocation

I have found that it has something to do with the this context in javascript, because when I change this implementation to:

sinon.log = function(){ console.log.apply(console, arguments) };

it works perfectly for n arguments (just as console.log does). But I don't know why should I set the this object to console object. Does it rely on internal browser implementation (I'm using chrome)? Is there any standard for that, eg I should always set this object to console in such case?

I ask for the explanation: how do the internals work, why is this error raised and why is my second implementation correct.

This works for me in a jsfiddle:

sinon.log = console.log.bind(console)

(jsfiddle: http://jsfiddle.net/vjotqjka/ )

console.log has a wierd behaviour with its this, which is why I used console.log.bind(console) to keep its this set to console. The behaviour of console.log with its this is not browser specific and is working as intended. This stackoverflow answer looks related: TypeError: Illegal Invocation on console.log.apply

More information about function.prototype.bind can be found here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM