Illegal invocation TypeError: Illegal invocation
时抛出 setTimeout
。我读到当this
引用回调中的另一个对象并且bind
或箭头函数用于解决此问题时,会发生这种情况。但是,我的回调中没有this
。
代码如下:
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');

请注意,我使用babel和es2015。
答案 0 :(得分:2)
在示例代码中,使用无效的上下文(this
)调用函数setTimeout和clearTimeout。可能的修复是绑定到正确的上下文(window
):
constructor(callback) {
this._alarms = {};
this.setTimeout = window.setTimeout.bind(window);
this.clearTimeout = window.clearTimeout.bind(window);
this._callback = callback || function () {};
}
通常会将函数内部的this
对象视为指向调用中点左侧的对象:
alerts.create(...) // inside create(), this === alerts
^
|___ "this"
如果没有点,则取决于调用者函数是否严格:
var create = alerts.create
create() // this === Window or global
^
|_____ no dot
和
'use strict'
var create = alerts.create
create() // this === undefined
^
|_____ no dot
鉴于我们在没有点的情况下致电setTimeout
,我们可能会认为this
背景并不重要。但是在浏览器中,如果你用点来调用它,或者使用一个作为上下文而不是窗口传递的变体,它会抱怨。
火狐:
未捕获的TypeError:非法调用
铬:
TypeError:' setTimeout'调用了一个没有实现接口Window的对象。
其他人建议坚持通常setTimeout(fn, timeout)
。
另一种方法是创建一个匿名函数:
this.setTimeout = (fn, timeout) => setTimeout(fn, timeout);
答案 1 :(得分:1)
回调中没有this
,但全局调用setTimeout
因此this.setTimeout
应为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

答案 2 :(得分:0)
我收到此错误是因为我将wanted context
而不是setTimeout
传递给了its callback
这是错误的代码,我在其中将this
传递给setTimeout
setTimeout.call(this, function () {
// this.model.starIcon = "fa-star";
this._toggleStarIcon()
}, 150);
传递上下文的正确方法是将其传递给setTimeout callback
我用$.proxy
做到了
这是正确的代码
setTimeout($.proxy(function () {
// this.model.starIcon = "fa-star";
this._toggleStarIcon()
}, this), 150);
希望这对您有帮助