Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript: Overwriting function's prototype - bad practice?

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:

function LolCat() { }  // at this point LolCat.prototype.constructor === LolCat  LolCat.prototype = {     hello: function () {         alert('meow!');     }     // other method declarations go here as well };  // But now LolCat.prototype.constructor no longer points to LolCat function itself  var cat = new LolCat();  cat.hello(); // alerts 'meow!', as expected  cat instanceof LolCat // returns true, as expected 

This is not how I do it, I still prefer the following approach

LolCat.prototype.hello = function () { ... } 

but I often see other people doing this.

So are there any implications or drawbacks by removing the constructor reference from the prototype by overwriting the function's prototype object for the sake of convenience as in the first example?

like image 743
Vitaly Avatar asked Sep 04 '12 09:09

Vitaly


People also ask

Why is it a bad idea to modify prototypes?

The problem is that prototype can be modified in several places. For example one library will add map method to Array's prototype and your own code will add the same but with another purpose. So one implementation will be broken.

Why is extending built-in JavaScript objects not a good idea?

Extending the JavaScript built-in object is not a good idea because if browser/JS has decided that they will provide the same method that you have extended, then your method will be override and the JS implementation (which may be difference from yours) would take over.

Should you use prototype in JavaScript?

You should use prototypes if you wish to declare a "non-static" method of the object. var myObject = function () { }; myObject.

What's the difference between prototype and __ proto __ in JavaScript?

prototype is a property of a Function object. It is the prototype of objects constructed by that function. __proto__ is an internal property of an object, pointing to its prototype.


2 Answers

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().

like image 134
Robin Winslow Avatar answered Oct 17 '22 23:10

Robin Winslow


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.

like image 25
Asciiom Avatar answered Oct 17 '22 23:10

Asciiom