0

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, e.g. 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.

6
  • Works for me in all browsers. jsBin Commented Aug 24, 2014 at 9:11
  • when I open chrome console and run the code from your fiddle, I get Illegal invocation error. Commented Aug 24, 2014 at 9:34
  • What's Chrome version? Commented Aug 24, 2014 at 9:38
  • It is not „this” the problem, but the console.@Zanval answer prove it.Also, you may write sinon.log = function(arg){console.log(arg);} without apply. Commented Aug 24, 2014 at 9:52
  • @hex494D49 version 36.0.1985.143 @cox I want to use arguments to get original console.log behavior (multiple arguments to be logged) - that's why I use .apply Commented Aug 24, 2014 at 10:03

1 Answer 1

1

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

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.