为什么长度属性在类似数组的对象中发生变化?

时间:2014-04-05 01:36:13

标签: javascript arrays

我正在编写有关JavaScript的callapply方法的教程,并且对示例中使用的“类数组对象”的行为感到困惑:

var arrayLikeObj = {
    0: 'Marty',
    1: 78,
    2: 42,
    3: ['Tim', 'Eric', 'Phil'],
    length: 4
};

我的理解是这里的length属性与Array.prototype.length方法完全无关,并且是硬编码的,以便为对象提供必要的类似数组的属性。

然而,当我pop类似于数组的对象时:

console.log(Array.prototype.pop.call(arrayLikeObj));

......它的长度属性已经减少了!

console.log(arrayLikeObj) // Object {0: "Marty", 1: 78, 2: 42, length: 3} 

这怎么可能!?

Array.prototype.length是否会以某种方式覆盖对象中的现有长度属性,将其转换为长度方法?

为了进一步引起我的困惑,当我声明一个没有硬编码length属性的对象并调用相同的pop方法时:

var arrayLikeObj = {
        0: 'Marty',
        1: 78,
        2: 42,
        3: ['Tim', 'Eric', 'Phil']
    };

console.log(Array.prototype.pop.call(arrayLikeObj));
console.log(arrayLikeObj);

返回的对象的长度为0:

{0: "Marty", 1: 78, 2: 42, 3: Array[3], length: 0}

我非常有兴趣了解这里发生的事情。

1 个答案:

答案 0 :(得分:3)

Array.prototype.pop为对象创建length属性。

http://www.ecma-international.org/ecma-262/5.1/#sec-15.4.4.6

它发生在步骤4.a和5.d中。在您发布的第二个案例中,请注意[[Get]]内部方法返回undefined(因为没有length属性),ToUint32(undefined)首先将undefined转换为NaN NaN然后将0转换为{{1}}。