我想完全克隆一个构造函数,所以它完全和原来一样,但它的原型被设置为原始的克隆。
我可以很容易地复制原来的原型就像这样:
// the original constructor function is assigned to the `type` variable.
const prototype = type.prototype;
const clonePrototype = Object.create(null);
const props = Object.getOwnPropertyNames(prototype);
for (let i = 0; i < props.length; ++i) {
const propertyName = props[i];
const propDescriptor = Object.getOwnPropertyDescriptor(prototype, propertyName);
Object.defineProperty(clonePrototype, propertyName,
Object.getOwnPropertyDescriptor(prototype, propertyName));
}
我遇到的问题是如何创建一个构造函数现在已经其prototype
属性设置为clonePrototype
对象。
如果我做:
const newContructor = function() {};
Object.setPrototypeOf(newContructor, clonePrototype);
然后newConstructor结束与__proto__
设置为clonePrototype
对象,并且prototype
属性不变。我想离开__proto__
不变,prototype
设置为新值。
我的目标是,使得它构造,其行为就像当初的原始类型的副本克隆这个构造函数,而是有其自己的原型。
我怎样才能做到这一点?
谢谢!
我会天真地告诉你两个解决方案:
我说天真,因为也许有一些用例需要克隆发生(或许一段时间后Type
原型随时间变化)。但是,由于你的代码示例,JavaScript的方式假定未修改的原型。
所以这是第一个。注意:我所做的更改是对函数表达式转换:
const newContructor = function() {};
一个函数声明:
function NewConstructor() {};
既然你Object.create
'd克隆,我把它Object.assign
'd原型。
function Type() {};
Type.prototype = {
a: 1,
b: 2,
c: function() {
console.log(this.a + " + " + this.b + " = " + (this.a + this.b));
}
}
const prototype = Type.prototype;
const clonePrototype = Object.create(null);
const props = Object.getOwnPropertyNames(prototype);
for (let i = 0; i < props.length; ++i) {
const propertyName = props[i];
const propDescriptor = Object.getOwnPropertyDescriptor(prototype, propertyName);
Object.defineProperty(clonePrototype, propertyName,
Object.getOwnPropertyDescriptor(prototype, propertyName));
}
function NewConstructor() {};
Object.assign(NewConstructor.prototype, clonePrototype);
/********************************************/
let type = new Type();
const cloned = new NewConstructor();
type.c(); // prints 1 + 2 = 3
cloned.c(); // prints 1 + 2 = 3
Object.getPrototypeOf(type).a = 0;
// Alternative syntax that some will dislike and point out it should not be used
cloned.__proto__.a = 3;
type.c(); // prints 0 + 2 = 2
cloned.c(); // prints 3 + 2 = 5
// Here are the independent prototypes (or type.__proto__ and cloned.__proto__
console.log(Object.getPrototypeOf(type), Object.getPrototypeOf(cloned));
如果原型是原始样机当克隆时,它是更直接的使用原型构造本身。这使您可以使用new
运营商与原型构建原型本身的Singleton实例。
在这个例子中,你会看到没有原型的克隆。原型的单版本为需要其作为原型的每个对象创建。
然后每个原型的突变被观察为彼此独立的:
function MyPrototype() {
this.a = 1;
this.b = 2;
this.c = function() {
console.log(this.a + " + " + this.b + " = " + (this.a + this.b));
};
}
function Type() {};
function NewConstructor() {};
Type.prototype = new MyPrototype();
NewConstructor.prototype = new MyPrototype();
/********************************************/
let type = new Type();
const cloned = new NewConstructor();
type.c(); // prints 1 + 2 = 3
cloned.c(); // prints 1 + 2 = 3
Object.getPrototypeOf(type).a = 0;
// Alternative syntax that some will dislike and point out it should not be used
cloned.__proto__.a = 3;
type.c(); // prints 0 + 2 = 2
cloned.c(); // prints 3 + 2 = 5
// Here are the independent prototypes (or type.__proto__ and cloned.__proto__
console.log(Object.getPrototypeOf(type), Object.getPrototypeOf(cloned));