0

我的印象是

setInterval("/*some code*/", time)

相当于

setInterval(function() {
   /*some code*/
}, time)

显然不是!请比较以下(完整的 HTML):

<pre id=p><script>n=setInterval("for(n+=7,i=k,P='p.\\n';i-=1/k;P+=P[i%2?(i%2*j-j+n/k^j)&1:2])j=k/i;p.innerHTML=P",k=64)</script>

<pre id=p><script>n=setInterval(function() { for(n+=7,i=k,P='p.\\n';i-=1/k;P+=P[i%2?(i%2*j-j+n/k^j)&1:2])j=k/i;p.innerHTML=P },k=64)</script>

这两个动画(第一个取自这里)是不同的。

为什么这两个构造不等价?

:至少有三个不同

  1. 变量范围
  2. 表现
  3. 字符串字符转义
4

3 回答 3

6

我没有研究过混淆代码,但是使用字符串和带有setTimeoutor的函数之间的区别在于setInterval代码运行的范围。此外,当您使用字符串时,某些引擎可能也无法优化。

  • 当您传入一个字符串时,它会在全局范围内运行。

  • 当您传入一个函数时,它会在定义它的范围内运行。

这会影响代码范围内的哪些变量,这会影响代码的作用。

这是一个未混淆的示例:Live copy | 来源

(function() {
  var foo = 42;

  // This will say "undefined", because there is no global `foo`
  setTimeout("display(typeof foo);", 0);

  // This will say "number", because the function is closure over
  // the current scope, whcih *does* have `foo`
  setTimeout(function() {
    display(typeof foo);
  }, 0);

})();

function display(msg) {
  var p = document.createElement('p');
  p.innerHTML = String(msg);
  document.body.appendChild(p);
}
于 2012-04-28T14:10:47.180 回答
3

这两种形式的 setInterval 本质上是等价的——但你的代码不是。在第二个示例中,您将换行符双重转义为\\n,而不仅仅是\n. 试试这个:

<pre id=p><script>n=setInterval(function() { for(n+=7,i=k,P='p.\n';i-=1/k;P+=P[i%2?(i%2*j-j+n/k^j)&1:2])j=k/i;p.innerHTML=P },k=64)</script>

这应该就像你想要的那样。

setInterval的function()形式在很多方面都更好——它更具可读性,而且当你遇到这里时,你不必处理试图在字符串中转义字符串。

于 2012-04-28T14:13:15.727 回答
1

我不确定我是否理解您的示例,但据我所知,两者之间的主要区别之一是 setInterval(string, time) 的性能将低于 setInterval(function, time) 因为它需要解释动态代码,与 eval() 相同。除此之外,您的代码每次都会操作 Dom,这会影响性能。

由于 javascript 是单线程的,因此 setInterval 中的间隔时间并不准确。请参阅 John Resig 的帖子:http ://ejohn.org/blog/how-javascript-timers-work/

我希望结果会根据 setInterval(string, time) 的性能消耗和非常小的间隔而有所不同。

于 2012-04-28T14:17:57.350 回答