For...in 循环导致潜在的内存不足崩溃
For...in loop causing potential out-of-memory crash
假设你有这么大 array
arr.
var arr = new Int32Array(99999999);
这两个for循环做不同的事情。这个暂停了很长一段时间,最终 returns 潜在的内存不足崩溃:
for (var i in arr) {console.log("done"); break;}
// --> Paused before potential out of memory crash.
虽然这一集立即结束:
for (var i = 0; i < arr.length; i++) {console.log("done"); break; }
// --> Finishes immediately.
我知道为什么第二个循环立即结束,但为什么第一个循环导致泄漏?
可能是因为 for...in
不保证 return 索引以任何特定顺序排列
根据mdn
for...in should not be used to iterate over an Array where the index
order is important.
在标准中,for...in
和 for...of
语句的执行包括一个从对象获取 BoundNames
的步骤。
参考https://www.ecma-international.org/ecma-262/6.0/#sec-for-in-and-for-of-statements.
这是简介:
BoundNames: Return a new List containing the StringValue of Identifier.
这意味着如果你正在迭代一个大数组,引擎必须在实际迭代发生之前获取一个包含数组的所有索引和其他属性的大List
。如果 List
太大,您会看到内存崩溃。
另一方面,在使用基于索引的 for
循环时,它不包括获取 List
步骤。
假设你有这么大 array
arr.
var arr = new Int32Array(99999999);
这两个for循环做不同的事情。这个暂停了很长一段时间,最终 returns 潜在的内存不足崩溃:
for (var i in arr) {console.log("done"); break;}
// --> Paused before potential out of memory crash.
虽然这一集立即结束:
for (var i = 0; i < arr.length; i++) {console.log("done"); break; }
// --> Finishes immediately.
我知道为什么第二个循环立即结束,但为什么第一个循环导致泄漏?
可能是因为 for...in
不保证 return 索引以任何特定顺序排列
根据mdn
for...in should not be used to iterate over an Array where the index order is important.
在标准中,for...in
和 for...of
语句的执行包括一个从对象获取 BoundNames
的步骤。
参考https://www.ecma-international.org/ecma-262/6.0/#sec-for-in-and-for-of-statements.
这是简介:
BoundNames: Return a new List containing the StringValue of Identifier.
这意味着如果你正在迭代一个大数组,引擎必须在实际迭代发生之前获取一个包含数组的所有索引和其他属性的大List
。如果 List
太大,您会看到内存崩溃。
另一方面,在使用基于索引的 for
循环时,它不包括获取 List
步骤。