Javascript Prototype Gets in the Way!

I have been re-reading eloquent javascript because I am taking up a class this summer that greatly deals with javascript. This book really helped me a lot transitioning from programming solely in Java to understanding some of the practical details of using javascript.


The Prototype

One of the sections in the book that i found really helpful was the explanation of how prototypes work. Prototype Interference in this section of the book (Secret life of Objects). If you are beginning javascript, how the prototype works in javascript is one of the fundamental concepts that you must grasp. There are probably several prototypes in javascript but the three prototypes that you might want to know about are

There are a lot of things in each prototype above and I will not discuss each in detail. Ultimately, prototypes are the object that is used as a fallback if the property or method is not on the current object you are referencing. You can also add new properties and method to all objects based on a prototype. But be careful because it might cause problems and I have spent many hours trying to debug javascript because of issues caused by modifying the prototype.

An Issue in overriding prototype  

To save you time, here is the some the issue I have encountered with prototypes.

Let's say that you are part of a team using javascript. One of your teammates decided to add a property in the Object.prototype and you did not know this.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
//Let's mess with the objects property
//You did not know somebody added a property //in the objects prototype
Object.prototype.protoProperty = 'propertyInPrototype';
var map = {};
map['firstEntry'] ='firstEntry';
map['secondEntry'] ='secondEntry';

for(var entry in map){

 console.log(entry);
}


With the code example above let's say you did not know that line 3 happened. At line 4 you created a new object and proceeded to add your properties. Once you have all your properties set. You tried and loop thru your properties and voila a mystery property appears and you will wonder where is it coming from!


If the property really needs to be in the prototype, this can be solved in different ways.
You can do your loop this way in order to ensure that the property is owned by the object

1
2
3
4
5
6
for(var entry in map){
 //check if the map has this property
 if(map.hasOwnProperty(entry)){
 console.log(entry); 
 } 
}
Declare the property in the prototype to be non-enumerable 


1
Object.defineProperty (Object.prototype , "protoProperty" , { enumerable : false , value : " propertyInPrototype "}) ;

Or better yet create objects that are prototype less
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
//Prototype less object
var map2 = Object.create(null);
map2['firstEntry2'] ='firstEntry2';
map2['secondEntry2'] ='secondEntry2';
console.log('toString' in map2);
console.log('\n');
for(var entry in map2){

 console.log(entry);
}


Good Luck!

Adding properties and functions in prototypes is not such a bad thing but be aware of some of the side effects of doing so.

Comments

Popular posts from this blog

OAuth 1.0a Request Signing and Verification - HMAC-SHA1 - HMAC-SHA256

Spark DataFrame - Array[ByteBuffer] - IllegalAurmentException

Gensim Doc2Vec on Spark - a quest to get the right Vector