2015-06-02 56 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