gpt4 book ai didi

javascript - 如何克隆一个构造函数,以便它构造一个原始类型的副本,其行为与原始类型一样,但有自己的原型(prototype)?

转载 作者:行者123 更新时间:2023-11-30 19:50:23 25 4
gpt4 key购买 nike

我正在尝试完全克隆构造函数,以便它与原始函数完全相同,但其原型(prototype)设置为原始函数的克隆。

我可以像这样轻松克隆原始原型(prototype):

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

我的目标是克隆这个构造函数,以便它构造一个原始类型的副本,其行为与原始类型一样,但有自己的原型(prototype)。

我怎样才能做到这一点?

谢谢!

最佳答案

我将天真地向您展示两种解决方案:

  1. 直接回答您的“如何做”问题(根据评论)
  2. 产生结果的 JavaScript 方式

我这么说很天真,因为也许有一些用例需要克隆发生(可能在 Type 原型(prototype)随时间改变后的某个时间)。但是,鉴于您的代码示例,JavaScript 方式假定未修改的原型(prototype)。

所以这是第一个。请注意,我所做的更改是转换函数表达式:

const newContructor = function() {};

函数声明:

function NewConstructor() {};

并且由于您Object.create 了克隆,我Object.assign 将其分配给了原型(prototype)。

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));

如果克隆发生时原型(prototype)是原始原型(prototype),则将原型(prototype)本身用作构造函数更为直接。这允许您将 new 运算符与您的原型(prototype)一起使用,以构造原型(prototype)本身的 Singleton 实例。

在此示例中,您将看不到原型(prototype)的克隆。为每个需要它作为原型(prototype)的对象创建原型(prototype)的单例版本。

然后观察到每个原型(prototype)的突变是相互独立的:

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));

关于javascript - 如何克隆一个构造函数,以便它构造一个原始类型的副本,其行为与原始类型一样,但有自己的原型(prototype)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54545198/

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