Как манипулировать свойствами объекта-прототипа?
Я пытаюсь сделать следующее:
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