2 回答
TA贡献1869条经验 获得超4个赞
什么都没有的数组元素叫做槽(slot),一般方法都会忽略,可以用 Array.prototype.fill、Array.from 或者 [...arr] 的方式转换。
比如 Array.from(new Array(4))
TA贡献1810条经验 获得超4个赞
这个你需要通过阅读V8引擎的源代码来获取答案:
function ArrayMap(f, receiver) {
CHECK_OBJECT_COERCIBLE(this, "Array.prototype.map");
// Pull out the length so that modifications to the length in the
// loop will not affect the looping and side effects are visible.
var array = TO_OBJECT(this);
var length = TO_LENGTH(array.length);
if (!IS_CALLABLE(f)) throw %make_type_error(kCalledNonCallable, f);
var result = ArraySpeciesCreate(array, length);
for (var i = 0; i < length; i++) {
if (i in array) {
var element = array[i];
%CreateDataProperty(result, i, %_Call(f, receiver, element, i, array));
}
}
return result;
}
在这里,我们注意到,它首先是用了一个TO_OBJECT来把数组转为了对象,然后用了一个for循环在对象中查找下标,也就是这一句话:if (i in array),而当我们用new Array(4)来创建数组时,实际创建的只是一个指针,并没有创建实体的4个元素,所以当它被转化为对象时,得到是{}这样的空对象,所以这里的每一个if语句分枝都不会被执行。
但如果我们用var array = [null, null, null, null]或者哪怕array = [undefined, undefined, undefined, undefined]来做,效果都会大不一样,因为以这样方式创建的数组,转化为的对象是:
{
0: undefined,
1: undefined,
2: undefined,
3: undefined,
}
当对这样的对象进行if (i in array)操作时,可以找到相应的下标,所以可以依次执行。这就是根本原因。
添加回答
举报
