我正在尝试按照本文Array
中给出的想法和建议进行子类化。
的这个子类的一个重要目标Array
,在这里我称之为ArrayBase
,是它本身的子类化比它自己更直接Array
。我发现实现这个目标非常困难。(但在我看来可能是这样,因为我是 JavaScript n00b!)
下面是一个实现,ArrayBase
它基于前面引用的文章结尾处提出的想法,并带有我自己的一些增强功能。我还包括了 的实现ArrayBase.slice
,因为它说明了方案1的一个问题。
function ArrayBase () {
var arr = Array.prototype.constructor.apply(null, arguments);
var ctor = arr.constructor = arguments.callee;
arr.__proto__ = ctor.prototype;
return arr;
}
ArrayBase.prototype = new Array;
ArrayBase.prototype.slice = function () {
var ctor = this.constructor;
return ctor.apply(null,
Array.prototype.slice.apply(this, arguments));
}
var a0 = new ArrayBase(0, 1, 2, 3);
var a1 = a0.slice(2); // [2, 3]
console.log(a1 instanceof ArrayBase); // true
console.log(a1 instanceof Array); // true
到目前为止,一切都很好。当我现在尝试子类化时,就会出现问题ArrayBase
。我发现做到这一点的唯一方法需要基本上复制整个ArrayBase
构造函数(唯一的区别,非常轻微,发生在第一行)。继承下去,这太可怜了……
function MyArray () {
var arr = ArrayBase.apply(this, arguments);
var ctor = arr.constructor = arguments.callee;
arr.__proto__ = ctor.prototype;
return arr;
}
MyArray.prototype = new ArrayBase;
// behavior of MyArray
var a2 = new MyArray(1, 2, 3, 0);
var a3 = a2.slice(1); // [2, 3, 0]
console.log(a3 instanceof MyArray); // true
console.log(a3 instanceof ArrayBase); // true
console.log(a3 instanceof Array); // true
console.log(a3.join(':')); // "2:3:0"
a3[5] = 1;
console.log(a3.length); // 6
a3.length = 2;
console.log(a3.toString()) // "2,3"
我的问题:
怎样才能消除存在于
ArrayBase
和MyArray
构造函数之间的重复,同时仍然保留行后行所说明的行为// behavior of MyArr
?该方案在子类化时是否也有效MyArray
?
(我知道反对建立高大的继承塔的论点,但无论它们是否是好的设计,我都希望它们至少能够得到很好的实施。)
1如果继承自是Array
我认为应该的那样,则没有必要实现ArrayBase.slice
,但不幸的是,继承自的slice
方法没有显示返回与 的对象相同类的对象的基本 OOP 礼貌。ArrayBase
Array
this