If I have a function (constructor) with a defined prototype, let's say:
function Student(name) {
this.name = name;
}
Student.prototype.sayHello = function() {
console.log(`Hello, my name is ${this.name}`);
}
And I instantiate and object using that function (from what I know it should set newly created object's property _prototype to the above prototype object in the moment of creation and set constructor property to Student function).
const s1 = new Student('John');
s1.sayHello();
I am sure calling sayHello() would work, however, what if I change the Student's prototype like this?
Student.prototype.sayGoodbye = function() {
console.log(`Goodbye, my name is ${this.name}`);
}
Should s1 be able to call sayGoodbye?
I've read that the _prototype should't change, so in that logic it should throw an error, however, trying it in Chrome's console panel and node.js project it worked and s1 could invoke sayGoodbye. Can someone help me understand this?
I am not sure what
_prototypemeans. Do you mean.__proto__? Or.prototype? Those two are different things (and.__proto__is deprecated, in favour ofObject.getPrototypeOfandObject.setPrototypeOf, and similarReflectmethods).There are a couple of different meanings of "change the prototype".
Replace the
[[Prototype]], like withObject.setPrototypeOf. Besides the possible implications on the readability, there is also the performance factor, summarised in this warning from the MDN:Modify the
[[Prototype]]of built-in or library objects, by replacing or adding properties. This is discouraged mainly because it is not future-proof. For example,Array.prototype.findis a pretty useful function, which did not exist in, say, 2012. If someone added it to the array prototype, it would have been useful then, but when it got implemented a few years later, anyone who definedArray.prototype.findon their own would have been replacing a more efficient code with the less efficient one.You could guard against it and only replace the function if it wasn't already defined, but then incompatibilities could arise. The now-standard
.findwill returnundefinedwhen it can't find a matching element. If your polyfill is returningnull, but you leave alone the built-in.findin case it exists, and your code behaves differently onnullandundefined, you have a problem.Modify the
[[Prototype]]of your own objects, by defining or replacing properties on the prototype. It seems this is the meaning you are using in your question. Shrug. It's your code.Yes, any changes to the prototype properties will be reflected in the prototyped objects, unless they are overshadowed by the properties on the prototyped objects. As deceze explains in their comment, the prototype properties are not copied onto the prototyped object at creation time. Instead, at lookup time, the property is checked on the prototyped object, then on the prototype, then on the prototype's prototype, going up the prototype chain until it is found (or, if no such property is found until the end of the chain is reached at the root object, returning
undefined). Thus, if you add a property to a prototype, it makes no difference when the property is added, whether before or after the creation of a prototyped object, as long as it is before the property is accessed.