是否有一个很好的理由传递一个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作为setTimeoutsetInterval第一个参数,那么互联网上将会有很多代码不再工作。

对于那些为什么传递一个函数比传递一个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); }); 

(其他对象可能或不可以通过 – 取决于它们是否可以被序列化,但总的来说,这将是相当困难的。)