2014-04-05 57 views
3

我通過對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)); 

...它的length屬性有所降低!

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} 

我對理解這裏發生的事情很感興趣。

+0

因爲那就是那些方法所做的。它被描述爲修改它給出的'this'對象的'.length'屬性。 [ECMAScript 5 - 15.4.4.6 Array.prototype.pop](http://es5.github.io/#x15.4.4.6)如果沒有'.length',它會得到一個默認的'0'值。 *「如果len爲零, a。調用O的[[Put]]內部方法,其參數爲」length「,0,且爲true; b。返回undefined」* –

+0

請注意,如果不是全部,大部分''Array.prototype'方法具有以下版本:*「'pop'函數是有意通用的;它不要求它的this值是一個Array對象,因此它可以被傳遞給其他類型的對象用作方法。「* –

+0

相關:[Array.prototype.slice.call()如何工作](http://stackoverflow.com/questions/7056925/how-does-array-prototype-slice-call-work ) –

回答

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)首先將undefinedNaN,然後轉換到NaN0

相關問題