最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

How do I pass console.log as an argument to my JavaScript function? - Stack Overflow

programmeradmin1浏览0评论

In the code below I can use print in place of console.log and the program can run correctly. However I wish to use console.log but I get

Illegal invocation

at runtime

function forEach(array, action) {
    for (var i=0; i<array.length; i++) 
        action(array[i]);
}

forEach(["blah", "bac"], console.log);

In the code below I can use print in place of console.log and the program can run correctly. However I wish to use console.log but I get

Illegal invocation

at runtime

function forEach(array, action) {
    for (var i=0; i<array.length; i++) 
        action(array[i]);
}

forEach(["blah", "bac"], console.log);
Share Improve this question asked Jan 29, 2012 at 10:02 deltanovemberdeltanovember 44.1k65 gold badges167 silver badges245 bronze badges 1
  • It will work if you pass only the console and call log inside the forEach function. – Thiago Augustus Oliveira Commented Jan 22, 2016 at 13:31
Add a ment  | 

3 Answers 3

Reset to default 7

In general you can't pass methods directly to callbacks in Javascript. The this is bound at the point of the function call, depending on what form you call it and there is no automatic binding of methods (like there is in, for example, Python)

//does not work.
var obj = {
    x: 17,
    f: function(){ return this.x; }
};

//inside doSomething, f forgets its "this" should be obj
doSomething( obj.f )

In these cases, one might use Function.prototype.bind (or a similar function from your library of choice, since bind is not present in IE <= 8)

//works (for normal methods - see next bit for console.log in particular)
var obj = {
    x: 17,
    f: function(){ return this.x; }
};

doSomething( obj.f.bind(obj) )

Unfortunately, however, this is not always enough for console.log. Since it is not an actual Function in IE, (its an evil host object) you cannot use bind, apply and call methods on it on that browser so the only workaround is falling back to wrapping the call in an anonymous function

doSomething( function(x){
    return console.log(x);
});

Since wrapping console.log in an anonymous function is long and annoying to type I usually add the following global function when I'm developing and debugging:

function log(message){ return function(x){
    return console.log(message, x);
};};

forEach(['asd', 'zxc'], log('->'));

From here : Create shortcut to console.log() in Chrome

You can replace console.log with console.log.bind(console)

Explanation thanks to @julian-d :

Because the console.log will refer internally to this and expects it to be console. If you 'detach' the log method e.g. like var log = console.log, this association is lost and this will no longer point to console (in this case to window instead - if you are in a browser). This is the purpose of .bind(obj): it returns a method where internally this stays fixed to obj.

You can solve the problem using an anonymous function acting as a bridge between forEach() and console.log()

forEach(["blah", "bac"], function (element) {
    console.log(element);
});

Your forEach() remains agnostic about the handler and you don't have to juggle with bind() to pass a working reference to console.log().

发布评论

评论列表(0)

  1. 暂无评论