Как манипулировать свойствами объекта-прототипа?

Я пытаюсь сделать следующее:

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

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


var someInstance = new SomeFunctionConstructor();

Теперь, если я console.log(someInstance), он печатает:

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

И теперь, когда я делаю someInstance.manipulatePrototype() а потом console.log(someInstance), он печатает:

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

Почему это создает новый someProtoVariable непосредственно на экземпляре вместо обновления someProtoVariable на прототипе?:(

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;

вызовет функцию установки и обновит значение "@property" в прототипе.

Я думаю, что вы путаете между экземпляром и прототипом. и экземпляр не может быть обработан по прототипу объекта. если это произойдет, то каждый экземпляр сможет разрушить цепочку прототипов и повлиять на все остальные экземпляры, созданные из этого прототипа.

если вы напечатаете someInstance.someProtoVariable без вызова манипуляции с Prototype, вы получите старое значение.

и после вы получите новое значение.
this.someProtoVariable переопределяет значение по умолчанию для экземпляра, но не переопределяет сам прототип

Вы можете прочитать больше о прототипе здесь Inheritance_and_the_prototype_chain

Другие вопросы по тегам