setTimeout Illegal invocation TypeError: Illegal invocation

Illegal invocation TypeError: Illegal invocation is thrown when calling setTimeout with a variable callback. I read that this happens when this refers to another object in the callback and that bind or arrow functions are used to solve this. However, no this in my callback.

The code is as follows:

class AlarmService {

    constructor(callback) {
        this._alarms = {};
        this.setTimeout = window.setTimeout;
        this.clearTimeout = window.clearTimeout;
        this._callback = callback || function () {};
    }

    create(alarmName, when, title, message) {
        this._alarms[alarmName] = {
            'title': title,
            'message': message
        };
        this._alarms.timeout = this.setTimeout(this._callback, when - Date.now(),
                               this._alarms[alarmName]);
    }
}

let alarms = new AlarmService(function (alarm) {
    console.log('Alarm', alarm.name);
});

// Exception is thrown here
alarms.create('alarmName', Date.now() + 3000, 'Title', 'Message'); 

In the sample code, functions setTimeout and clearTimeout are being invoked with an invalid context (this). On possible fix is binding to the correct context (window):

constructor(callback) {
    this._alarms = {};
    this.setTimeout = window.setTimeout.bind(window);
    this.clearTimeout = window.clearTimeout.bind(window);
    this._callback = callback || function () {};
}

It is usual to think of the this object inside a function pointing to the object to the left of the dot in the invocation:

alerts.create(...) // inside create(), this === alerts
   ^
   |___ "this"

When there's no dot, it depends whether the caller function is strict:

var create = alerts.create
create() // this === Window or global
^
|_____ no dot

And

'use strict'
var create = alerts.create
create() // this === undefined
^
|_____ no dot

Given we call setTimeout without a dot, we may think that the this context doesn't matter. But in browsers it will complain if you call it with a dot, or use a variant that pass as context something different than window.

Firefox:

Uncaught TypeError: Illegal invocation

Chrome:

TypeError: 'setTimeout' called on an object that does not implement interface Window.


Others suggested sticking to the usual setTimeout(fn, timeout). Yet another way is creating an anonymous function:

this.setTimeout = (fn, timeout) => setTimeout(fn, timeout);

Javascript TypeError - Illegal invocation, Javascript TypeError - Illegal invocation - undefined in chrome //ex.message && ex.name setTimeout("runScreenJson()", 1000); } }); } catch  You just have to pass it (the object which will be used as context) as a first parameter to this method. For example alert.call({}) gives TypeError: Illegal invocation. However, alert.call(window) works fine, because now alert is executed in its original scope. If you use .call() with your object like that:


There is no this in your callback, however setTimeout is called globally. So this.setTimeout should be setTimeout

class AlarmService {

    constructor(callback) {
        this._alarms = {};
        this.setTimeout = window.setTimeout;
        this.clearTimeout = window.clearTimeout;
        this._callback = callback || function () {};
    }

    create(alarmName, when, title, message) {
        this._alarms[alarmName] = {
            'title': title,
            'message': message
        };
        this._alarms.timeout = setTimeout(this._callback, when - Date.now(), this._alarms[alarmName]);
    }
}

let alarms = new AlarmService(function (alarm) {
    console.log('Alarm', alarm);
});

alarms.create('alarmName', Date.now() + 3000, 'Title', 'Message'); // Exception is thrown here

Error: "Uncaught TypeError: Illegal invocation" · Issue #986 , a List component, do I get the exception Uncaught TypeError: Illegal invocation in Chrome. Yeah, that should be raf.call(window, timeout) . At least on Chromium 73 when opening the extension options window an exception "TypeError: Illegal invocation: Function must be called on an object of type StorageArea" is thrown, which results in empty update channels page. It looks like chrome.storage.local methods need to be called while bound to the chrome.storage.local object.


I got this error because I passed the wanted context to setTimeout instead of its callback

this the wrong code, where I pass this to setTimeout

setTimeout.call(this, function () {
    // this.model.starIcon = "fa-star";
    this._toggleStarIcon()
}, 150);

I correct way to pass you context is to pass it to setTimeout callback

I used $.proxy to do that

here is the correct code

setTimeout($.proxy(function () {
    // this.model.starIcon = "fa-star";
    this._toggleStarIcon()
}, this), 150);

hope this helps you

Illegal Invocation error when used in a web-worker · Issue #1732 , jdthorpe changed the title Illegal Invocation error in web-worker Illegal Invocation error Error: TypeError: Illegal invocation innerHTML = ` var done = function(){ clearTimeout(t); } var t = setTimeout(done,100) ` script.onerror  It works fine, but every time it fires there's a message in the console: "Uncaught TypeError: Illegal invocation (jquery.js:2970)". Even having a function like


setTimeout Illegal invocation TypeError: Illegal invocation, Illegal invocation TypeError: Illegal invocation is thrown when calling setTimeout with a variable callback. I read that this happens when this  Uncaught (in promise) TypeError: Failed to execute 'fetch' on 'Window': Illegal invocation. and on Firefox with. Function.prototype.bind called on incompatible target. Interestingly, Safari doesn't care. The following workaround works well.


javascript - Uncaught TypeError: Illegal invocation, The other thing this does is push the function invocation to the bottom of the stack​, preventing a stack javascript - Why is setTimeout(fn, 0) sometimes useful? Got the TypeError: Illegal invocation when getting the locator #5774. Closed Copy link Quote reply Member jennifer setTimeout (resolve, 1000);})


The most concise screencasts for the working developer, updated daily. There's no shortage of content at Laracasts. In fact, you could watch nonstop for days upon days, and still not see everything!