【问题标题】:Strange results of script execution in Chrome, Opera and Safari consoleChrome、Opera 和 Safari 控制台中脚本执行的奇怪结果
【发布时间】:2016-12-03 11:11:45
【问题描述】:

这是一个脚本:

for(var i = 0; i < 5; i++) {
  setTimeout(function() { console.log(i); }, 0);
};

理论上它应该在控制台中只输出五个“5”。但是当我们在 Chrome、Opera 或 Safari 控制台中执行它时,除了结果之外还有一些奇怪的数字。操作系统为 macOS Sierra 10.12.1。

例如

Chrome 54.0.2840.98(64 位):

for(var i = 0; i < 5; i++) {
      setTimeout(function() { console.log(i); }, 0);
    };
2105
⑤ 5

Safari 10.0.1:

> for(var i = 0; i < 5; i++) {
      setTimeout(function() { console.log(i); }, 0);
    };
< 6
> for(var i = 0; i < 5; i++) {
      setTimeout(function() { console.log(i); }, 0);
    };
< 11
> for(var i = 0; i < 5; i++) {
      setTimeout(function() { console.log(i); }, 0);
    };
< 16

Opera 39.0:

for(var i = 0; i < 5; i++) {
      setTimeout(function() { console.log(i); }, 0);
    };
5
⑤ 5                                    VM73:2
for(var i = 0; i < 5; i++) {
      setTimeout(function() { console.log(i); }, 0);
    };
10
⑤ 5                                    VM74:2

你可以自己试试。有趣的是 - HTML 页面中包含的相同代码可以正常工作。根据打开的控制台的选项卡,数字是不同的。它是什么?猜猜它是某种用于循环的内部计数器,但不确定。另一个想法 - 控制台显示执行函数的返回值。也许是的。但是for 不返回任何内容。至少不应该。相同的代码但没有setTimeout 显示undefined 而不是奇怪的数字,因为它应该可以工作。也许有人比我和互联网更了解它。任何想法都受到高度赞赏。对不起我的英语不好。谢谢!

【问题讨论】:

  • 使用let而不是var将变量限制在同一范围内
  • 在 Chrome 和 Opera 示例中,2105 是setTimeout 调用产生的最终计时器。 ⑤ 5 表示数字5 显然已经输出了五次。 Safari 似乎也在打印计时器 ID,虽然我不知道为什么它不输出 i,可能是控制台设置问题。
  • 我不关心⑤ 5,主要问题是关于for 函数的“结果”中的奇怪数字。
  • @Endless,至少在 Chrome 中没关系。

标签: javascript google-chrome safari opera developer-tools


【解决方案1】:

这是最小的例子:

for(var i = 0; i < 5; i++) setTimeout(function() {})
> 71 (or whatever)

虽然语句没有值,但控制台会尝试“提供帮助”并输出最后评估的表达式返回的内容 - 在本例中,它是 setTimeout(...),它返回超时 ID - 一些任意数字。

【讨论】:

  • 您可能是对的,但是...尝试按顺序执行此代码。它会给你(在我的情况下)75、80、85、90、95、100 等......所以基本上它增加了 5(循环迭代次数),这就是为什么这个数字是有趣的?
  • @Serj.by:超时 ID 似乎是按顺序分配的,所以是的,您的代码分配了 5 个超时并返回最后一个 ID。将“随机”编辑为“任意”以避免混淆;)
【解决方案2】:

它可能正在打印来自setTimeout 的返回值。可以使用clearTimeout 清除它。如果再次运行,您将获得另一个值,因为每个超时都应该有自己的唯一编号来停止它。

同时,您可能已过滤控制台以仅显示 错误 将其更改为显示 all 以查看实际日志。我猜现在 DevTools 默认只有 errors。 (野生动物园)

【讨论】:

  • 感谢您的回答! clearTimeout 然而会立即销毁超时,虽然它需要一些时间来执行,所以什么都不会被执行。 for (var i=0; i &lt; 5; i++) { var to = setTimeout(function () { console.log(i); }, 0); clearTimeout (to); } undefined 也许你提到了别的东西?但是清除超时会给出可预测的未定义结果。无论如何,它没有在 setTimeout 中执行代码。
  • 我刚才说返回的数字作为唯一ID来清除超时。 setTimeout 返回唯一 ID 的原因。
  • 哦,好的,知道了。对不起,误会你了。看起来它真的是这样工作的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-16
  • 2011-01-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多