当执行的方法(即,分配给对象的功能),在其内部可以使用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
同样的事情,当你指定的window
方法到另一个对象发生。诸如此类的本机功能具有内置保护,以免在其他情况下执行它。
有一个Function.prototype.call()
函数,它允许你在另一个上下文中调用一个函数。您只需将它传递(将用作上下文的对象)作为此方法的第一个参数。例如alert.call({})
给出TypeError: Illegal invocation
。但是,alert.call(window)
工作正常,因为现在alert
在其原始范围内执行。
如果使用.call()
与你的对象像:
support.animationFrame.call(window, function() {});
因为是在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,其is not supported in IE <= 8的一部分。幸运的是,有a polyfill on MDN。
正如您可能已经知道的那样,您可以使用.bind()
始终在window
的上下文中执行。您的代码可能如下所示:
var support = {
animationFrame: (window.requestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.msRequestAnimationFrame ||
window.oRequestAnimationFrame).bind(window)
};
然后您可以简单地使用support.animationFrame(function() {});
。
从Chrome 33起,第二次调用失败以及“非法调用”。一旦答案[更新](http://stackoverflow.com/a/13278323/1269037),快乐删除downvote! – 2014-03-06 13:19:44
@DanDascalescu:我使用的是铬合金33,它适用于我。 – Nemoy 2014-03-10 02:30:15
我刚刚复制粘贴你的代码,并得到非法的调用错误。 (http://imgur.com/oTDsazG) – 2014-03-10 03:22:47