谷歌浏览器 console.log 乱序? [复制]

Posted

技术标签:

【中文标题】谷歌浏览器 console.log 乱序? [复制]【英文标题】:Google Chrome console.log out of sequence? [duplicate] 【发布时间】:2011-12-29 14:37:53 【问题描述】:

有人可以解释以下两个输出吗?

代码 1:

console.log(itemsAry);
//loadNextItem();
function loadNextItem()
    var item = itemsAry.shift();
    console.log(item);

结果:

["cat-53", "cat-57", "cat-51", "cat-10", "cat-55", "cat-56", "cat-5", "cat-50", "cat-3", "cat-54", "cat-52", "cat-9", "cat-8", "cat-4", "cat-58", "cat-6", "cat-7"]

(如预期)。

代码 2:

console.log(itemsAry);
loadNextItem();
function loadNextItem()
    var item = itemsAry.shift();
    console.log(item);

结果:

["cat-57", "cat-51", "cat-10", "cat-55", "cat-56", "cat-5", "cat-50", "cat-3", "cat-54", "cat-52", "cat-9", "cat-8", "cat-4", "cat-58", "cat-6", "cat-7"]

cat-53

请注意,cat-53 已从原始数组 PRIOR 转移到 console.log() 输出,该输出应该在 shift 操作发生之前发生。我怎么可能?或者我错过了什么?

编辑:情况变得更糟:

console.log(itemsAry);
loadNextItem(); loadNextItem(); loadNextItem(); loadNextItem();
function loadNextItem()
    var item = itemsAry.shift();
    console.log(item);
    console.log(itemsAry);

结果:

["cat-55", "cat-56", "cat-5", "cat-50", "cat-3", "cat-54", "cat-52", "cat-9", "cat-8", "cat-4", "cat-58", "cat-6", "cat-7"]
cat-53
["cat-55", "cat-56", "cat-5", "cat-50", "cat-3", "cat-54", "cat-52", "cat-9", "cat-8", "cat-4", "cat-58", "cat-6", "cat-7"]
cat-57
["cat-55", "cat-56", "cat-5", "cat-50", "cat-3", "cat-54", "cat-52", "cat-9", "cat-8", "cat-4", "cat-58", "cat-6", "cat-7"]
cat-51
["cat-55", "cat-56", "cat-5", "cat-50", "cat-3", "cat-54", "cat-52", "cat-9", "cat-8", "cat-4", "cat-58", "cat-6", "cat-7"]
cat-10

在 FireFox 中进行测试后,这似乎是特定于 Google Chrome 的问题。 FF 输出:

["cat-53", "cat-57", "cat-51", "cat-10", "cat-55", "cat-56", "cat-5", "cat-50", "cat-3", "cat-54", "cat-52", "cat-9", "cat-8", "cat-4", "cat-58", "cat-6", "cat-7"]
cat-53
["cat-57", "cat-51", "cat-10", "cat-55", "cat-56", "cat-5", "cat-50", "cat-3", "cat-54", "cat-52", "cat-9", "cat-8", "cat-4", "cat-58", "cat-6", "cat-7"]
cat-57
["cat-51", "cat-10", "cat-55", "cat-56", "cat-5", "cat-50", "cat-3", "cat-54", "cat-52", "cat-9", "cat-8", "cat-4", "cat-58", "cat-6", "cat-7"]
cat-51
["cat-10", "cat-55", "cat-56", "cat-5", "cat-50", "cat-3", "cat-54", "cat-52", "cat-9", "cat-8", "cat-4", "cat-58", "cat-6", "cat-7"]
cat-10
["cat-55", "cat-56", "cat-5", "cat-50", "cat-3", "cat-54", "cat-52", "cat-9", "cat-8", "cat-4", "cat-58", "cat-6", "cat-7"]

按预期输出...

【问题讨论】:

【参考方案1】:

console.log的行为

execute scope 中的 console.log 快​​照元素并在控制台中打印它们。这里有一个演示:

(function () 
  console.log(obj);
  var obj= ;
  obj.new_value = 'hello';
())

obj 在调用console.log 时未定义。但它使用正确的属性new_value 打印到控制台中。

火狐的问题

首先,在firefox中使用function关键字声明函数时,函数名要等到代码执行后才会赋值。

如果你之前的代码中没有定义loadNextItem,下面的代码会在firefox中产生一个错误(ReferenceError: loadNextItem is not defined)。

loadNextItem();

function loadNextItem ()
    var item = itemsAry.shift();
    console.log(item);

ECMA-262 中说明了此行为

众所周知,一些广泛使用的 ECMAScript 实现支持将 FunctionDeclaration 用作语句。然而,在应用于此类 FunctionDeclarations 的语义中,实现之间存在显着且不可调和的变化。由于这些不可调和的差异,将 FunctionDeclaration 用作 Statement 会导致代码在实现之间无法可靠地移植。

还有firefox doesn't support这种行为。

【讨论】:

您是否建议 Firefox 不会执行某个函数,除非该函数已被定义为 FIRST(在代码中)? 并非如此。如果你使用 函数字面量 var myFunc = function() ,你可以在范围内的任何地方使用它们。 它就是受不了,恐怕。即使最简单的测试用例在你说它会失败的地方也会成功。我不太确定您正在测试哪个浏览器版本,但在最新版本的 FF(至少 6+)上,您可以从定义它的位置提前(在代码中)调用函数。 嗨,Tom,我在 FF7.0 上进行了测试,代码如下var itemsAry = [1,2,3]; loadNextItem(); function loadNextItem () var item = itemsAry.shift(); console.log(item); ; 你能提供我正在使用的测试用例吗?这是一个严重的问题,不利于我对 JS 中函数声明的理解。 我已经尝试了您引用的完全相同的代码,它按预期工作。请注意,我在 FF8 中进行测试,但我在 javascript 中声明它们多年之前一直在使用函数,并且从未遇到过这个问题。我相信它与解释器有关——它首先编译所有函数,然后执行。所以它永远不会成为问题。【参考方案2】:

我认为您使用的是 Chrome 是否正确? Firebug 不会这样做(我刚刚检查过 - FF8.0、FB 1.8.4),但 Chrome 16 会。

我认为正在发生的事情是,在 Chrome 中,console.log() 是异步执行的,以免中断您的代码或其他东西;实际上,所有的 console.log() 都会在调用它们的代码完成运行后立即发生。

编辑:诅咒,忍者!

【讨论】:

【参考方案3】:

无法在 FF 8.0 中复制使用

x = [1,2,3,4,5];
console.log(x);
y();
function y() 
    z = x.shift();
    console.log(z);

【讨论】:

可在 Chrome 上的 Firebug lite 上重现:jsfiddle.net/aNRe2.【参考方案4】:

console.log 总是有点“迟到”,当涉及到对象时,你不能指望它。只有原语(字符串等)才能直接工作。前者在内存中只有一个实例,所以当控制台获取数据时,它可能已经改变了。

当然,这取决于您实际使用的控制台,但我经常在 Chrome 上遇到这种情况。

Here is someone who experienced this on Firebug.

【讨论】:

@Tom Auger,@pimvdb console.log 不是“迟到”,但它在执行范围内输出 object,就像闭包一样。 如果您遇到问题的情况,您可以console.log(JSON.stringify(itemsAry)); 就可以了。这是延迟的非标量类型的扩展,当您扩展输出时会弹出一个微小的i,上面写着“刚刚评估了下面的项目”

以上是关于谷歌浏览器 console.log 乱序? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

事件传播与 React 冒泡乱序

JS 获取当前浏览器宽高

TypeError: can't convert console.log(...) to primitive type

JavaScript--兼容问题总结

sort排序

为啥全局变量不添加到浏览器的窗口对象? [复制]