Javascript 通过原型继承扩展ES2015
我正在制作一个库,在这里我想提供一个助手来扩展基类,这样即使用户自己不使用ES2015,也可以扩展它。问题是,如果基类恰好位于ES2015中(因为它不是通过transpiler发送的),则我从子类调用父构造函数失败,原因是: 类构造函数Foo不能在没有“new”的情况下调用 我正在努力实现的示例:Javascript 通过原型继承扩展ES2015,javascript,oop,ecmascript-6,Javascript,Oop,Ecmascript 6,我正在制作一个库,在这里我想提供一个助手来扩展基类,这样即使用户自己不使用ES2015,也可以扩展它。问题是,如果基类恰好位于ES2015中(因为它不是通过transpiler发送的),则我从子类调用父构造函数失败,原因是: 类构造函数Foo不能在没有“new”的情况下调用 我正在努力实现的示例: class Foo { constructor() { console.log("In Foo"); } superMethod() { return console.l
class Foo {
constructor() {
console.log("In Foo");
}
superMethod() {
return console.log("In super method");
}
static classMethod() {
return console.log("In class method");
}
}
Foo.extendClass = function (constructor, methods) {
const currentClass = this;
if (typeof constructor !== 'function') {
methods = constructor;
constructor = function () {
return Object.getPrototypeOf(constructor).apply(this, arguments);
};
}
constructor.prototype = Object.create(currentClass.prototype, {
constructor: {
value: constructor,
writable: true,
configurable: true
}
});
Object.setPrototypeOf(constructor, currentClass);
Object.assign(constructor.prototype, methods);
return constructor;
};
const Bar = Foo.extendClass({
subMethod: function() {
return console.log("In sub method");
}
});
b = new Bar();
问题出在这一行:
return Object.getPrototypeOf(constructor).apply(this, arguments);
那么我如何调用父级的构造函数呢?我原以为ES2015只是标准原型继承之上的一块糖,但看起来你无法模拟它?在运行时定义子类还有其他方法吗?ES6在
[[Call]]
和[[Construct]]
操作之间建立了更清晰的区别。ES6类只能使用[[Construct]]
操作构造,但是.call
/.apply
是[[call]]
操作。要使用[[Construct]]
,您需要使用Reflect.Construct()
来创建新实例。e、 g
constructor = function () {
return Reflect.construct(Object.getPrototypeOf(constructor), arguments);
};
或
不过,我还要注意,这也忽略了ES6中的另一个新特性,即new.target
。你也会希望通过这样做来保持这一点
constructor = function () {
return Reflect.construct(currentClass, arguments, new.target);
};
以确保这些东西的行为方式与类语法相同
还请注意,您不得在此函数中使用此。它是新实例的Reflect.construct
的返回值,因此如果您想在自己的自定义构造函数中使用它,您需要执行以下操作
constructor = function () {
const _this = Reflect.construct(currentClass, arguments, new.target);
_this.foo = "foo";
return _this;
};
然而,如果你想一想,这基本上和你所做的是一样的
constructor = class extends currentClass {}
谢谢这是一个惊人的答案!
constructor = class extends currentClass {}