2016-06-21 119 views
109

在Chrome控制台执行这段代码:为什么typeof null的值在循环内部发生变化?

function foo() { 
 
    return typeof null === 'undefined'; 
 
} 
 
for(var i = 0; i < 1000; i++) console.log(foo());

应打印1000次false,但在某些机器会打印false多次迭代,那么true为休息。

enter image description here

这究竟是为什么?它只是一个错误?

+4

它正在返回1000倍对我来说是真的... –

+2

我认为它的错误,我有262错误/ 738真正 –

+1

铬的控制台它是奇怪的:如果你推到一个数组并记录数组,它都是假的'。按原样,“真实”的数量在铬中波动。 – dandavis

回答

37

它实际上是一个V8 JavaScript引擎(Wiki)的错误。

这台发动机在铬,Maxthron,Android操作系统,使用的Node.js等

相对简单bug description你可以找到在这个Reddit topic

现代JavaScript引擎编译JS代码为优化机代码 执行(即时编译)使其运行更快。 但是,优化步骤在 交换中有一些初始性能成本,以便长期加速,所以引擎根据使用的频率动态决定 是否值得。

在这种情况下,仅在优化路径中出现错误 而未优化路径正常工作。所以起初该方法的工作原理是 ,但如果它在某个循环中被足够频繁地调用,那么引擎将决定优化它,并用缺陷版本 替换它。

这个bug似乎已经在V8本身(commit)得到修复,藏汉如铬(bug report)和的NodeJS(commit)。

+0

我确认这个bug仍然在Node.js 6.2.2里面让我很担心。 –

+0

今天(21.06)它已经在V8引擎中修复了,我相信相关的软件很快就会被更新。 –

+0

将v8修复反向移植到Node.js 6.2.x已经在进行中,因为[TheAlphaNerd]拥有的问题[#7348](https://github.com/nodejs/node/pull/7348)(https:// github的.com/TheAlphaNerd)。 –

18

为了回答它为什么会发生变化的直接问题,该错误发生在Chrome使用的V8 JS引擎的“JIT”优化例程中。起初,代码完全按照书面形式运行,但运行得越多,优化的好处就越有可能超过分析成本。

在这种情况下,在循环中重复执行后,JIT编译器会分析该函数,并将其替换为优化版本。不幸的是,分析做出了不正确的假设,而优化后的版本实际上并没有产生正确的结果。

具体而言,Reddit user RainHappens suggests它处于型传播一个错误:

它还执行某种类型的传播(如在什么类型的变量等即可)。当变量未定义或为空时,有一种特殊的“不可检测”类型。在这种情况下,优化云“null是检测不到的,所以它可以与被替换‘的比较未定义’串

这是与优化代码的难题之一:如何保证其具有代码被重新排布的性能仍然会与原先相同的效果。

相关问题