当我尝试创建Type Error
的本地引用时,我遇到了这种奇怪的window.requestAnimationFrame
。以下按预期工作,并将记录Foo
:
var foo = window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(fn){ setTimeout(fn, 1000 / 24); };
foo(function(){ console.log('Foo') });
然而,当我绑定到父对象时,它不起作用并抛出Type Error
,我不得不说让我困惑:
var bar = {};
bar.foo = window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(fn){ setTimeout(fn, 1000 / 24); };
bar.foo(function(){ console.log('Bar.Foo') });
即使window
或window.requestAnimationFrame
永远不是undefined
,调用它们在嵌套时会抛出类型错误。但是,当我比较两个变量时,它们被认为是等于。是否有一个原因?有没有办法在对象内部对正确的实现进行工作引用?
document.body.innerHTML += 'About to call Foo: <br />';
try {
var foo = window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(fn){ setTimeout(fn, 1000 / 24); };
foo(function(){ document.body.innerHTML += '<i>Foo</i><br />'; });
} catch(e){
document.body.innerHTML += '<i> >>> Error thrown when calling Foo.</i><br />';
}
document.body.innerHTML += 'About to call Bar.Foo: <br />';
try {
var bar = {};
bar.foo = window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(fn){ setTimeout(fn, 1000 / 24); };
bar.foo(function(){ document.body.innerHTML += '<i>Bar.Foo</i><br />'; });
} catch(e){
document.body.innerHTML += '<i> >>> Error thrown when calling Bar.Foo.</i><br />';
}
document.body.innerHTML += foo === bar.foo
? '<strong>Foo and Bar.Foo are considered the same</strong><br />'
: '<strong>Foo and Bar.Foo are NOT considered the same</strong><br />';
body {
font-family: Monaco, 'Courier MS', Coureire, mono-space;
}
答案 0 :(得分:1)
好吧,requestAnimationFrame
是DOM API的一部分,它不是JavaScript对象,因此很难确定它失败的原因。请记住:
this
设置为调用者对象,在您的情况下,该对象为bar
且没有window
所有属性。window
调度JavaScript函数 - 因此调用window.alert
和alert
是一回事(严格模式除外)。 因此,在某处使用this
的幕后完全可能。然后,它又是一个主机对象&#34;所以所有赌注都已关闭。
这是类似的&#34;普通&#34; JS代码具有相同的行为。
window.msg = "Hello";
function foo(){
if(this !== window) throw new TypeError("Illegal Invocation");
alert(this.msg);
}
foo(); // alerts hello, `this` is window
window.foo(); // alerts hello
var bar = {};
bar.foo = foo;
bar.foo(); // typeerror
&#13;
解决方法是将其包装在匿名函数中或使用bind
。
答案 1 :(得分:1)
试试这个
var bar = {};
bar.foo = (window.requestAnimationFrame && window.requestAnimationFrame.bind(window)) ||
(window.webkitRequestAnimationFrame && window.webkitRequestAnimationFrame.bind(window)) ||
(window.mozRequestAnimationFrame && window.mozRequestAnimationFrame.bind(window)) ||
(window.msRequestAnimationFrame && window.msRequestAnimationFrame.bind(window)) ||
function(fn){ setTimeout(fn, 1000 / 24); };
bar.foo(function(){ console.log('Bar.Foo') });
这为{requestAnimation设置this
到窗口对象
根据@poke的评论
var bar = {};
bar.foo = (window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(fn){ setTimeout(fn, 1000 / 24); }).bind(window);
bar.foo(function(){ console.log('Bar.Foo') });