给定课程
class Test {
test() {
console.log('test called');
}
}
还有一些对象toExtend = {}
如何扩展此对象以使其具有test
方法?
Object.assign
(以及_.extend
,_.assign
,$.extend
)不会复制方法。什么是最好的方法呢?
请注意toExtend
从外部传递
UPD:
toExtend
是另一个类的实例,并拥有自己的原型方法
答案 0 :(得分:9)
对于以自己的原型(Object.getPrototypeOf(toExtend) === Object.protoype)
)开头的对象文字,您只需使用Object.setPrototypeOf
来扩展对象:
class Test {
test() {
console.log('test called');
}
}
const toExtend = {};
// Set the prototype, so you "inherit" methods:
Object.setPrototypeOf(toExtend, Test.prototype);
toExtend.test();

在较旧的运行时中,您必须手动分配原型:
function Test() {
// noop ctor
}
Test.prototype.test = function() {
console.log('test called');
};
var toExtend = {};
// Set the prototype, so you "inherit" methods:
toExtend.__proto__ = Test.prototype;
toExtend.test();

对于现有类的实例,事情要复杂得多。他们确实拥有自己的原型,可能具有必须复制的属性,因此您需要完成这些:
class Foo {
test() {
console.log('test');
}
}
class Bar {
toast() {
console.log('toast');
}
}
function dynamicExtend(target, base) {
const baseProto = Object.getPrototypeOf(target);
if (baseProto == Object.prototype) {
// simple case: no existing prototype
Object.setPrototypeOf(target, base.prototype);
} else {
// complex case: existing prototype
const proxyClass = class extends base {};
const proxyProto = proxyClass.prototype;
// assign the target properties
Object.getOwnPropertyNames(baseProto).forEach(n => {
const desc = Object.getOwnPropertyDescriptor(baseProto, n);
Object.defineProperty(proxyProto, n, desc);
});
Object.setPrototypeOf(target, proxyProto);
}
}
const targets = [{},
new Bar()
];
targets.forEach(t => {
dynamicExtend(t, Foo);
t.test();
if (t.toast) {
t.toast();
}
});

请注意,由于代理类,这会破坏instanceof
样式继承检查。
__proto__
在评论{@ 3}}中为@PatrickRoberts noted,因此您应尽可能选择setPrototypeOf
。