在Chrome控制台中执行以下代码段:
function foo() {
return typeof null === 'undefined';
}
for(var i = 0; i < 1000; i++) console.log(foo());
应该打印1000次false
,但在某些机器上将打印false
多次迭代,然后true
进行其余迭代。
为什么会这样呢?这只是一个错误吗?
false
。照原样true
,铬的s 数量会波动。
在Chrome控制台中执行以下代码段:
function foo() {
return typeof null === 'undefined';
}
for(var i = 0; i < 1000; i++) console.log(foo());
应该打印1000次false
,但在某些机器上将打印false
多次迭代,然后true
进行其余迭代。
为什么会这样呢?这只是一个错误吗?
false
。照原样true
,铬的s 数量会波动。
Answers:
实际上,这是一个V8 JavaScript引擎(Wiki)错误。
该引擎用于Chromium,Maxthron,Android OS,Node.js等。
现代JavaScript引擎在执行时(及时编译)将JS代码编译为优化的机器代码,以使其运行更快。但是,优化步骤需要一定的初始性能成本,以换取长期的加速,因此引擎会根据使用的频率来动态地决定一种方法是否值得。
在这种情况下,似乎仅在优化路径中存在错误,而未优化路径则可以正常工作。因此,一开始该方法可以按预期工作,但是如果在某个时刻被足够频繁地循环调用,引擎将决定对其进行优化并将其替换为越野车版本。
为了回答为什么会更改的直接问题,该错误在Chrome使用的V8 JS引擎的“ JIT”优化例程中。刚开始,代码的运行与编写时完全相同,但是运行的次数越多,优化带来的好处就越有可能超过分析成本。
在这种情况下,在循环中重复执行后,JIT编译器将分析该函数,并用优化的版本替换它。不幸的是,该分析做出了错误的假设,并且优化版本实际上未产生正确的结果。
具体来说,Reddit用户RainHappens认为这是类型传播中的错误:
它还进行一些类型传播(如变量等可以是什么类型)。当变量未定义或为null时,有一种特殊的“无法检测”类型。在这种情况下,优化器将变为“ null is not detectable,因此可以将其替换为” undefined”字符串以进行比较。
这是优化代码的难题之一:如何确保为性能而重新安排的代码仍具有与原始代码相同的效果。
该问题已在两个月前修复,即将在Chrome中投放(已经在Canary中投放)。