2015-06-02 92 views
-1

在以下片段中,子類數組的行爲與原始數組的行爲不同。爲什麼?子類數組的長度

function Arr() {} 
Arr.prototype = new Array(); 

var iArr = new Arr();  
iArr[0] = 9; 
iArr[5] = 10; 
console.log(iArr.length); 
console.log(iArr[0]); 
console.log(iArr[5]); 
iArr.push(87); 
console.log(iArr.length); 
console.log(iArr[0]); 
console.log(iArr[5]); 

結果

0 
9 
10 
1 
87 
10 

var iArr = new Array(); 
iArr[0] = 9; 
iArr[5] = 10; 
console.log(iArr.length); 
console.log(iArr[0]); 
console.log(iArr[5]); 
iArr.push(87); 
console.log(iArr.length); 
console.log(iArr[0]); 
console.log(iArr[5]); 

6 
9 
10 
7 
9 
10 

我本來預期的第一個片段爲好。

我不明白爲什麼第一個片段的長度屬性沒有通過索引訪問元素而改變。

+3

[你可以在不ES5子陣列(http://perfectionkills.com/how-ecmascript-5-still- do-not-allow-to-subclass-an-array /) –

+0

在這種情況下,這意味着什麼?未定義的行爲?那麼ES6(iojs)呢? – JeffRSon

+0

密切相關:[使用setPrototypeOf進行數組子類化](http://stackoverflow.com/q/27985546/710446) – apsillers

回答

1

length行爲僅適用於由Array構造函數通過new Array創建的對象。即length自動行爲僅適用於正品Array實例。在此,您擁有的唯一Array實例爲Arr.prototype,即iArr的原型父項。 iArr不是由new Array創建的,所以它沒有得到神奇的length行爲。

iArr上的設置值不會以任何方式操縱原型父級,因此您的Array實例未修改,這意味着length未修改。

當你調用iArr.push,你也不修改父Array實例,但the ES5 spec for push要求push設置到任何對象的length屬性呼籲:

  • 調用參數"length",ntrue的[[Put]]內部方法O
  • 對於這樣的作品,使用ES6技術的實例,請參見Array subclassing with setPrototypeOf