是否有一个很好的理由传递一个stringsetTimeout?
我们都知道传递给setTimeout
(或setInterval
)的string是邪恶的,因为它在全局范围内运行,性能问题,如果你注入任何参数,可能是不安全的。所以这样做是绝对不推荐的:
setTimeout('doSomething(someVar)', 10000);
赞成这个:
setTimeout(function() { doSomething(someVar); }, 10000);
我的问题是:能否有一个理由去做前者? 它是可取的吗? 如果不是,为什么甚至允许?
我想到的唯一情况是想要使用一个函数或variables,它存在于全局作用域中,但已在本地作用域中被覆盖。 这听起来像糟糕的代码devise,但是…
你可以使用全局variables作为窗口对象的属性,比如window.globalVar
(虽然使用全局variables确实不是一个好习惯),所以不用,我不认为有一个很好的理由来使用已经废弃的句法。
这可能是由于历史的原因:Felix Kling提到,原始语法只允许传递一串代码:
引入了JavaScript 1.0,Netscape 2.0。 在JavaScript 1.2,Netscape 4.0中引入了传递函数对象引用 ; 自5.0版本开始支持MSHTML DOM。 [ 来源 ,我的重点]
如果浏览器不支持使用string作为setTimeout
和setInterval
第一个参数,那么互联网上将会有很多代码不再工作。
对于那些为什么传递一个函数比传递一个string更重要的问题 。
1:传递一个string会启动一个编译器
每次你必须评估一个string,你会激发一个完整的编译器。 对于每个需要的调用。
这不仅速度很慢,而且会破坏所有JIT和浏览器的加速工作。
2:传递一个string更有限。
因为string是通过编译器运行的,所以它不像本地范围和variables那样干净地绑定。
虽然这种情况并不明显,例如:
window.setInterval("doThing()");
在更复杂的情况下,代码只是更干净:
window.setInterval("doThing(" + val1 + "," + val2 + ")");
VS
window.setInterval(function() { // You can put a debugging point here dothing(val1, val2); });
3:DOM对象不能通过string传递
正如Álvaro提到的,DOM对象不能通过string方法传递。
// There is no way to do this via a string. var el = document.getElementById("my-element"); window.setInterval(function() { dothing(el); });
(其他对象可能或不可以通过 – 取决于它们是否可以被序列化,但总的来说,这将是相当困难的。)