gpt4 book ai didi

javascript - 尝试实现一个简单的 -"subclassable"数组子类

转载 作者:行者123 更新时间:2023-11-29 22:09:16 25 4
gpt4 key购买 nike

我正在尝试子类化 Array ,遵循 this article 中给出的想法和建议.

Array 这个子类的一个重要目标,这里我称之为 ArrayBase , 是它本身比 Array 更容易被子类化吗?本身。我发现实现这个目标出奇地困难。 (但在我看来可能是这样,因为我是 JavaScript 新手!)

下面是 ArrayBase 的实现这是基于提出的想法towards the end前面引用的文章的一部分,加上我自己的一些改进。我还包含了 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"

我的问题:

How could the duplication that exists between the ArrayBase and MyArray constructors, be eliminated, while still preserving the behavior illustrated by the lines after the // behavior of MyArr line? Would the scheme work also at the time of subclassing MyArray?

(我知道反对 build 继承高塔的争论,但无论它们是否是好的设计,我都希望它们至少得到妥善实现。)


1如果继承自Array正如我认为的那样,没有必要实现 ArrayBase.slice , 但不幸的是 slice ArrayBase 的方法继承自 Array不显示返回与 this 属于同一类的对象的基本 OOP 礼貌.

最佳答案

在回答你的问题之前,先对代码做一些评论:-)

var arr = Array.prototype.constructor.apply(null, arguments);

因为 Array.prototype.constructor === Array,所以不要复制它。

var ctor = arr.constructor = …

没有理由在这里创建属性。如果任何东西都需要 constructor 属性,则应该从该构造函数的 .prototype 对象继承它。

arguments.callee;

不要使用已弃用的 arguments.callee!您知道它指向 ArrayBase

arr.__proto__ = ctor.prototype;

您可能知道 __proto__ 是非标准的(尤其是在 IE 中不起作用),但我们在这里需要它来实现原型(prototype)注入(inject)技术。不过,不要忘记这个事实!

ArrayBase.prototype = new Array;

not use new for setting up inheritance !您不想在这里调用初始化程序(即“构造函数”)。请改用 Object.create

现在,回到你的问题:

How can the duplication that exists between my ArrayBase and MyArray constructors be eliminated?

其实你已经用过这个概念了。您的 ArrayBase.prototype.slice 实现适用于每个子类 - 再次构造 this.constructor 的实例。您可以对 ArrayBase 构造函数使用相同的方法:

function ArrayBase() {
var arr = Array.apply(null, arguments);
var ctor = this.constructor;
arr.__proto__ = ctor.prototype;
return arr;
}
/* irrelevant for the answer, but helpful:
ArrayBase.prototype = Object.create(Array.prototype, {
constructor: {value: ArrayBase}
});
Object.keys(Array.prototype).forEach(function(k) {
if (typeof Array.prototype[k] != "function") return;
ArrayBase.prototype[k] = function() {
var arr = Array.prototype[k].apply(this, arguments);
if (Array.isArray(arr))
arr.__proto__ = Object.getPrototypeOf(this);
return arr;
};
});
*/
function MyArray() {
return ArrayBase.apply(this, arguments);
}
MyArray.prototype = Object.create(ArrayBase.prototype, {
constructor: {value: MyArray}
});

关于javascript - 尝试实现一个简单的 -"subclassable"数组子类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18970703/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com