Since when we declare a function we get its prototype\'s constructor property point to the function itself, is it a bad practice to overwrite function\'s prototype like so:<
This form:
LolCat.prototype = {
hello: function () {
alert('meow!');
}
};
Destroys any existing methods and public properties. In the example, as given, it doesn't matter as the newly created LolCat doesn't have any properties or methods. However, one should be mindful of this in more complicated code.
This form:
LolCat.prototype.hello = function () { ... }
Adds a new method to an existing object and keeps the existing intact.
After many years of javascript, I stumbled upon a weird bug where a new instance of an object, then passed in a mixin had lost its __proto__
when its prototype
class were declared with :
MyClass.prototype = {
constructor: MyClass,
myMethod(){ ...}
};
There is no anymore problem when using :
Object.assign( MyClass.prototype, {
myMethod(){ ...}
});
Bonus : you don't have to reasign the construct anymore.
I guess it is because when we overwrite totally the prototype property, we wipe also its specials attributes and transform it as a normal one...maybe this one should not be writable by default...
Its not a bad practice to overwrite the constructor
when using prototypal inheritance. Infact many people do it like so:
LolCat.prototype = {
constructor: LolCat,
hello: function () {
alert('meow!');
}
};
Its not a bad practice. But there is a simple and standard way of overriding a function like below. When ever we define a 'function LolCat()' globally, its created under window so you can always code like below.
window.LolCat = function() {...};
LolCat.prototype.hello = function () { ... }
I can't see anyone mentioning best practice as far as this is concerned, so I think it comes down to whether you can see the constructor
property ever being useful.
One thing worth noting is that the constructor
property, if you don't destroy it, will be available on the created object too. It seems to me like that could be useful:
var ClassOne = function() {alert("created one");}
var ClassTwo = function() {alert("created two");}
ClassOne.prototype.aProperty = "hello world"; // preserve constructor
ClassTwo.prototype = {aProperty: "hello world"}; // destroy constructor
var objectOne = new ClassOne(); // alerts "created one"
var objectTwo = new ClassTwo(); // alerts "created two"
objectOne.constructor(); // alerts "created one" again
objectTwo.constructor(); // creates and returns an empty object instance
So it seems to me that it's an architectural decision. Do you want to allow a created object to re-call its constructor after it's instantiated? If so preserve it. If not, destroy it.
Note that the constructor of objectTwo is now exactly equal to the standard Object constructor function - useless.
objectTwo.constructor === Object; // true
So calling new objectTwo.constructor()
is equivalent to new Object()
.
It's not bad practice but you have to know what you are doing and why. It is very useful for prototypal inheritance. The object of which you overwrite the prototype will get all the properties of the object you assign to it's prototype:
You cause an object to inherit using
ChildClassName.prototype = new ParentClass();.
Now ChildClassName has all functionality of ParentClass but loses any functionality that was assigned to it's prototype before. You need to remember to reset the constructor property for the object using
ChildClassName.prototype.constructor=ChildClassName.
Otherwise the object will be reported to be (when testing for the type of an object) of the ParentClass type instead of the ChildClassName type.
And now you can add more methods to the ChildClassName object in the way you described yourself.
ChildClassName.prototype.myMethod = function(){
//do stuff
}
The result being a parent object/'class'(there are no real classes in javascript of course) and a child object/'class' that inherits from it and extends its functionality.
You just have to know that if you overwrite the prototype, any properties that where assigned to it will be gone. When constructing inheriting objects this might be exactly what you want.