0

我正在尝试执行以下操作:

function SomeFunctionConstructor() {
   this.someMainVariable = "someValue";
   this.manipulatePrototype = () => {
     this.someProtoVariable = "some new value";
   }
}

SomeFunctionConstructor.prototype.someProtoVariable = "Some proto value";


var someInstance = new SomeFunctionConstructor();

现在,如果 I console.log(someInstance),它会打印:

{
  someMainVariable: 'someValue',
  manipulatePrototype: [Function] 
}

现在,当我这样做时someInstance.manipulatePrototype()console.log(someInstance)它会打印:

{
  someMainVariable: 'someValue',
  manipulatePrototype: [Function],
  someProtoVariable: 'some new value' 
}

为什么它someProtoVariable直接在实例上创建一个新的而不是someProtoVariable在原型上更新?:(

4

2 回答 2

2

如果你真的想修改一个对象原型的属性,你可以通过构造函数直接引用原型:

SomeConstructor.prototype.property = newValue;

Object.getPrototypeOf()在实例上使用:

Object.getPrototypeOf(someInstance).property = newValue;

现在,通常事情会变得有点复杂,因为一个实例的原型链中可能有多个对象。在这种情况下,您可能想要什么取决于您的应用程序。

请注意,更改原型上的属性值将具有使该属性在所有实例上具有新值的效果。

您可以向原型添加一个setter函数以自动执行此操作:

Object.defineProperty(SomeConstructor.prototype, "property", {
  value: someInitialValue,
  set: function(value) {
    Object.getPrototypeOf(this)["@property"] = value;
  },
  get: function() {
    return Object.getPrototypeOf(this)["@property"];
  }
});

它使用另一个名为“@property”的原型属性(可以是任何名称,或者更好的Symbol实例)来存储“属性”的表观值。接着就,随即,

someInstance.property = newValue;

将调用 setter 函数并更新原型上的“@property”值。

于 2018-08-20T18:34:07.030 回答
1

我认为您在实例和原型之间感到困惑。并且实例无法通过设计超越对象原型。如果发生这种情况,那么每个实例都将能够破坏原型链并影响从该原型构建的所有其他实例

如果您打印 someInstance.someProtoVariable 而不调用操作原型,那么您将获得旧值。

之后你会得到新的价值。
this.someProtoVariable 确实覆盖了实例的默认值,但没有覆盖原型本身

你可以在这里阅读更多关于原型的信息 Inheritance_and_the_prototype_chain

于 2018-08-20T18:01:17.963 回答