2012-06-15 89 views
0

根据this answer我要创造我自己的Array我的数组的子类不调用超级构造

QArray = function() { 
    Array.apply(this, arguments); 
}; 
QArray.prototype = new Array(); 
QArray.prototype.constructor = QArray; 

预期其子类的工作,方法调用工作,但构造并不链阵列。

// test constructor chaining 
q = new QArray('1', '2', '3'); 
assert.equals('1', q[0]);  // => undefined 
assert.equals(3, q.length); // => 0 
q = new QArray(10); 
assert.equals(10, q.length); // => 0 

该测试通过,如果我用普通Array取代QArray。不知何故Array似乎是一个特例。 (我在使用Javascript 1.5的Rhino 1.6中运行这个)。我该如何修复Array的自定义子类?

回答

1

因为你的方法已经继承了阵列的方法,你可以使用修改的按键排列方式,如Array.prototype.push

QArray = function() { 
    if (arguments.length == 1) this.length = arguments[0]; // Array constructor 
    else this.push.apply(this, arguments); 
}; 
QArray.prototype = new Array(); 
QArray.prototype.constructor = QArray; 

q = new QArray('1', '2', '3'); // => [1,2,3] 
assert.equals('1', q[0]);  // => true 
assert.equals(3, q.length);  // => true 
q = new QArray(10);    // => [,,,,,,,,,] 
assert.equals(10, q.length);  // => true 
q instanceof QArray;    // => true 
q instanceof Array;    // => true 

我曾经写了一个自定义的数组实现,其行为像一个真正的数组(包括length setter/getter)。如果你需要灵感,看看this answer

+0

谢谢。是的,我可以重新实现'Array.prototype.constructor'逻辑。但为什么我必须? –

+0

@PeterKofler由于Array构造函数不修改数组,但创建并返回新数组:'var a = []; Array.call(a)== a;'(false),反对'var a = [] ; Array.prototype.reverse.call(a)== a;'(true)。 –

+0

谢谢。这适用于构造函数。所有的数组方法工作**但**'q = new QArray(); q [3] ='芒果'; q.length // => 0而不是4',所以当直接用'q []'设置新元素时,长度不会更新。 –

相关问题