Chrome 中的“未捕获的类型错误:非法调用”
"Uncaught TypeError: Illegal invocation" in Chrome
当我使用requestAnimationFrame
使用以下代码制作一些本机支持的动画时:
var support = {
animationFrame: window.requestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.msRequestAnimationFrame ||
window.oRequestAnimationFrame
};
support.animationFrame(function() {}); //error
support.animationFrame.call(window, function() {}); //right
直接打电话给support.animationFrame
会得到...
未捕获类型错误:非法调用
在铬中。为什么?
在代码中,您将本机方法分配给自定义对象的属性。当你调用support.animationFrame(function () {})
时,它是在当前对象的上下文(即支持(中执行的。要使本机 requestAnimationFrame 函数正常工作,必须在 window
的上下文中执行它。
所以这里的正确用法是 support.animationFrame.call(window, function() {});
.
警报也会发生同样的情况:
var myObj = {
myAlert : alert //copying native alert to an object
};
myObj.myAlert('this is an alert'); //is illegal
myObj.myAlert.call(window, 'this is an alert'); // executing in context of window
另一种选择是使用 Function.prototype.bind((,它是 ES5 标准的一部分,可在所有现代浏览器中使用。
var _raf = window.requestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.msRequestAnimationFrame ||
window.oRequestAnimationFrame;
var support = {
animationFrame: _raf ? _raf.bind(window) : null
};
您还可以使用:
var obj = {
alert: alert.bind(window)
};
obj.alert('I´m an alert!!');
当你执行一个方法(即分配给对象的函数(时,你可以在其中使用this
变量来引用这个对象,例如:
var obj = {
someProperty: true,
someMethod: function() {
console.log(this.someProperty);
}
};
obj.someMethod(); // logs true
如果将方法从一个对象分配给另一个对象,则其this
变量引用新对象,例如:
var obj = {
someProperty: true,
someMethod: function() {
console.log(this.someProperty);
}
};
var anotherObj = {
someProperty: false,
someMethod: obj.someMethod
};
anotherObj.someMethod(); // logs false
当您将requestAnimationFrame
window
方法分配给另一个对象时,也会发生同样的事情。本机函数(例如此类(具有内置保护,以防止在其他上下文中执行它。
有一个Function.prototype.call()
函数,它允许您在另一个上下文中调用函数。您只需将其(将用作上下文的对象(作为第一个参数传递给此方法。例如,alert.call({})
给出TypeError: Illegal invocation
.但是,alert.call(window)
工作正常,因为现在alert
在其原始范围内执行。
如果像这样对对象使用.call()
:
support.animationFrame.call(window, function() {});
它工作正常,因为requestAnimationFrame
是在window
范围内而不是您的对象中执行的。
但是,每次要调用此方法时都使用 .call()
并不是非常优雅的解决方案。相反,您可以使用 Function.prototype.bind()
.它与.call()
具有类似的效果,但它不是调用函数,而是创建一个始终在指定上下文中调用的新函数。例如:
window.someProperty = true;
var obj = {
someProperty: false,
someMethod: function() {
console.log(this.someProperty);
}
};
var someMethodInWindowContext = obj.someMethod.bind(window);
someMethodInWindowContext(); // logs true
Function.prototype.bind()
的唯一缺点是它是 ECMAScript 5 的一部分,IE <= 8 不支持它。幸运的是,MDN 上有一个填充物。
您可能已经发现,您可以使用.bind()
始终在window
上下文中执行requestAnimationFrame
。您的代码可能如下所示:
var support = {
animationFrame: (window.requestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.msRequestAnimationFrame ||
window.oRequestAnimationFrame).bind(window)
};
然后你可以简单地使用 support.animationFrame(function() {});
.
这是一个非常常见的问题,与 JavaScript 中的绑定以及this
如何工作有关——
假设我有一个像这样的函数document.write
,如果我直接调用它,就像下面一样,写函数知道this
指的是document
对象,但是在 JavaScript 中有一个叫做隐式损失的东西,或者至少我们是这样引用它的
document.write("Hello"); // Write is aware of this
如果我为函数制作一个别名(它不是副本(,document.element
到像 x
这样的变量,你可能会期望函数会像以前一样继续工作,对吧?
let x = document.write // x is just a refrence to the write function
不,函数x
只是函数的别名write
函数是大多数浏览器中的本机函数,这意味着它由浏览器实现。 x
不知道document
对象,因此调用时this
的全局范围是函数的this
。
因此,如果您调用函数x
它会给您非法调用错误,并且为了能够使用它,您必须x
意识到this
,这就是所谓的explicit binding
,您可以使用这样的call
或bind
使用它
x.call(document, "Hello, World!");
// Or you can use bind, which will create a new function
x.bind(document)("Hello, World!");
就我而言,解决此问题的正确提示是通过 XXX.catch(( 承诺方法正确处理错误和记录承诺。然后核心问题出现了,我可以处理它。
- 如何解决这种情况下的非法调用类型错误
- 未捕获的语法错误:意外的令牌非法?看起来不错
- 未捕获的类型错误:非法调用:模态形式的错误
- 非法调用错误 jquery
- Ajax 帖子未捕获语法错误:意外令牌非法
- 为什么这会引发未捕获的类型错误:非法调用
- 未捕获的语法错误:非法返回语句
- 尝试将javascript转换为jquery时出现错误“非法调用”
- 为什么我收到错误“语法错误:非法字符”
- jQuery突然:未捕获类型错误:非法调用
- Chrome 中的“未捕获的类型错误:非法调用”
- 未捕获的类型错误:非法的构造函数jquery-1.10.0.js
- 类型错误:非法调用console.log.apply
- 将email id作为参数发送给javascript函数:语法错误非法字符
- 未捕获的类型错误:非法调用addEventListener
- JavaScript未捕获类型错误非法调用
- 未捕获的类型错误:非法调用
- 读取CSV错误:非法数据.什么'正在发生
- 是什么导致了“未捕获的类型错误:非法调用”?在这段代码中
- 什么是Chrome中的“未捕获的类型错误:非法调用”