如何克隆一个构造函数,这样它构造,其行为就像当初的原始类型的副本,但有自己的原型?

问题描述 投票:1回答:1

我想完全克隆一个构造函数,所以它完全和原来一样,但它的原型被设置为原始的克隆。

我可以很容易地复制原来的原型就像这样:

  // 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设置为新值。

我的目标是,使得它构造,其行为就像当初的原始类型的副本克隆这个构造函数,而是有其自己的原型。

我怎样才能做到这一点?

谢谢!

javascript prototype prototype-programming
1个回答
1
投票

我会天真地告诉你两个解决方案:

  1. 直接回答你“如何做”的问题(每评论)
  2. 产生结果的JavaScript的方法

我说天真,因为也许有一些用例需要克隆发生(或许一段时间后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));
© www.soinside.com 2019 - 2024. All rights reserved.