In the section about inheritance in the MDN article Introduction to Object Oriented Javascript, I noticed they set the prototype.constructor:
// correct the constructor pointer because it points to Person
Student.prototype.constructor = Student;
Does this serve any important purpose? Is it okay to omit it?
Given simple constructor function:
By default (from the specification https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/constructor), all prototypes automatically get a property called constructor that points back to the function on which it is a property. Depending on the constructor, other properties and methods might be added to the prototype which is not a very common practice but still it is allowed for extensions.
So simply answering: we need make sure that the value in prototype.constructor is correctly set as it is supposed by the specification to be.
Do we have to always set correctly this value? It helps with debugging and makes internal structure consistent against specification. We should definitely when our API is being used by the thirdparties, but not really when the code is finally executed in the runtime.
I'd disagree. It isn't necessary to set the prototype. Take that exact same code but remove the prototype.constructor line. Does anything change? No. Now, make the following changes:
and at the end of the test code...
The color will be blue.
A change to the prototype.constructor, in my experience, doesn't do much unless you're doing very specific, very complicated things that probably aren't good practice anyway :)
Edit: After poking around the web for a bit and doing some experimentation, it looks like people set the constructor so that it 'looks' like the thing that is being constructed with 'new'. I guess I would argue that the problem with this is that javascript is a prototype language - there is no such thing as inheritence. But most programmers come from a background of programming that pushes inheritence as 'the way'. So we come up with all sorts of things to try and make this prototypical language a 'classic' language.. such as extending 'classes'. Really, in the example they gave, a new student is a person - it isn't 'extending' from another student.. the student is all about the person, and whatever the person is the student is as well. Extend the student, and whatever you've extended is a student at heart, but is customized to fit your needs.
Crockford is a bit crazy and overzealous, but do some serious reading on some of the stuff that he's written.. it'll make you look at this stuff very differently.
No need for sugared function 'classes' or using 'New' these days. Use object literals.
The Object prototype is already a 'class'. When you define an object literal, it is already an instance of the prototype Object. These can also act as another object's prototype, etc.
This is worth a read:
It is not necessary. It is just one of the many things traditional, OOP champions do to try to turn JavaScript's prototypical inheritance into classical inheritance. The only thing that the following
does, is that you now have a reference of the current "constructor".
In Wayne's answer, that has been marked as correct, you could the exact same thing that the following code does
with the code below (just replace this.constructor with Person)
Thank God that with ES6 classical inheritance purists can use language's native operators like class, extends and super and we don't have to see like prototype.constructor corrections and parent refereces.
So far confusion is still there.
Following the original example, as you have an existing object
student1
as:Suppose you don't want to know how
student1
is created, you just want another object like it, you can use the constructor property ofstudent1
like:Here it will fail to get the properties from
Student
if the constructor property is not set. Rather it will create aPerson
object.It's not always necessary, but it does have its uses. Suppose we wanted to make a copy method on the base
Person
class. Like this:Now what happens when we create a new
Student
and copy it?The copy is not an instance of
Student
. This is because (without explicit checks), we'd have no way to return aStudent
copy from the "base" class. We can only return aPerson
. However, if we had reset the constructor:...then everything works as expected: