当 new Array(len)
时,我观察到一个现象:
const arr = new Array(100);
arr.forEach(() => console.log(123));
这种情况下 console.log 并不会输出,所以这里传入的并不是 length,而是 capacity?
如果我们创建一个全为 undefined 的数组,他是可以被遍历输出的:
[undefined, undefined, undefined].forEach(console.log)
建议看下mdn吧 . 关键在于forEach const arr = new Array(100); 创建出来的是类似于这种 [,] 100个,Array.prototype.forEach() 不对未初始化的值进行任何操作(稀疏数组)
并不一样,js array 没有 capacity 的概念,不需要手动去扩容,并且 const arr = new Array(100);
也不是 [undefined, undefined, …] 这样的 100 个 undefined
元素,而是 v8 的一个特殊 value hole
,类似 [hole, hole, …] 这样的,无法被遍历
相信我,为了优化,V8什么事都干得出来。。
@hyj1991 按道理来说,如果先声明一个空数组,然后不停往里 push,是会导致底层频繁扩容,会影响性能的,但是我测试了一下:
- 声明空数组,往里push一百万次
- new Array(一百万),然后直接向对应的 index 赋值
空数组居然比提前声明容量的方式快一倍还多。。。我也没查到是为啥
@willx12123 我知道为什么了,跟 v8 的底层实现有关系,如果出现了稀疏数组,那底层用的就是 HashTable 储存,不然的话是类似 ArrayList 的结构,叫 FixedArray,HashTable 肯定就很慢了