41

I'm creating a lambda function that executes a second function with a concrete params. This code works in Firefox but not in Chrome, its inspector shows a weird error, Uncaught TypeError: Illegal invocation. What's wrong with my code?

var make = function(callback,params){
    callback(params);
}

make(console.log,'it will be accepted!');
Matias Kinnunen
  • 7,828
  • 3
  • 35
  • 46
fcortes
  • 1,338
  • 3
  • 11
  • 26
  • 1
    if i replace `console.log` with `console.log.bind(console)`, it works in Chrome 12. – Dan D. Jan 18 '12 at 03:31
  • 2
    @DanD—that indicates that *log* expects to be called as a method of *console*, i.e. that its *this* keyword must reference the *console* object. – RobG Jan 18 '12 at 03:36
  • your `make` function is equivalent to `callback.call(null,params)` – Jan Turoň May 17 '13 at 18:53
  • I would like to note that in old versions of IE console.log can be a callable host-object (without call, apply or bind methods) instead of being a function. – hugomg Jan 22 '14 at 18:35
  • https://stackoverflow.com/a/71283695/12910765 – Rana Nadeem Feb 27 '22 at 09:47

2 Answers2

70

The console's log function expects this to refer to the console (internally). Consider this code which replicates your problem:

var x = {};
x.func = function(){
    if(this !== x){
        throw new TypeError('Illegal invocation');
    }
    console.log('Hi!');
};
// Works!
x.func();

var y = x.func;

// Throws error
y();

Here is a (silly) example that will work, since it binds this to console in your make function:

var make = function(callback,params){
    callback.call(console, params);
}

make(console.log,'it will be accepted!');

This will also work

var make = function(callback,params){
    callback(params);
}

make(console.log.bind(console),'it will be accepted!');
Paul
  • 139,544
  • 27
  • 275
  • 264
4

You can wrap the function which need 'this' to a new lambda function, and then use it for your callback function.

function make(callback, params) {
  callback(params);
}

make(function(str){ console.log(str); }, 'it will be accepted!');
ifreedom
  • 426
  • 3
  • 4