It is true that javascript is very different from other programming languages, so maybe that’s why lots of people even professional programmers don’t think javascript is a good language and don’t understand it well. A year ago, I had the same feeling, but after I started my work of front-end web development and read the book “Javascript: The good parts”, I have to say I am falling in love with this beautiful and powerful language. One of the most beautiful part of javascript is its prototype property, which makes the inheritance easily.
First of all, we must know that every object in javascript has an internal prototype property(in order to distinguish it with function’s external prototype property, I would use [prototype] to denote internal ones). There are three ways that you can use to create an object:
1. var obj = {};
2. var obj = new Object;
3. var obj = Object.create(null);
All of these three ways are equivalent in creating an empty object. Once the object was created, it will have that internal [prototype] property, note that [prtotype] is still an object so it also has internal prototype prototype property of which value is the object that is inherited from Object’s external prototype. How can we access to the internal [prototype]? A standard way is to use Object.getPrototypeof(), the other way that you can use is the __proto__ property, but I think it is only built in Chrome.
Function is also a kind of object in javascript, but function has an unique property which is the external prototype. This external prototype property is the important key for us to implement OOP in javascript. The normal way of implementation of OOP is like this:
function Person(){
this.name = "Tom";
this.age = 23;
}
Person.prototype.run = function(){
console.log(this.name+" is running! ");
}
var p = new Person(); //this will create an instance of Person
p.run();
Now, let me explain the above codes:
You may ask what happened when we use the new keyword. Actually, when new keyword is used, three things happened:
1. An empty object is created, just like {}, very simple.
2. It sets the function’s prototype property’s value to the instance object’s internal [prototype], so here, we can say
p.__proto__ = Person.prototype
3. The function’s constructor will be executed, in which the constructor is the constructor in that function’s external prototype. Then the instance will replace this in the constructor. In this example, p will have property name and age.
Oh, here is another thing I need to mention. When access to a property of an object, it will firstly detect whether the object has the property directly, if not then goes to its [prototype] ,if still not, goes to [prototype]’s [prototype]…until reaching the root and return found or not found. That’s another important concept in javascript, called prototype chain. In the above example, it is easy to find the property ‘name’ and ‘age’ as they are directly attached to that object. But if we want to check if the object has ‘run’ property, since it is not attached to that object directly, we need to go deeper to p.__proto__ which is inherited from Person.prototype(Remind!), now we find ‘run’.
The problem here is that why we do not put ‘run’ in Person’s constructor directly? Why we attach it to prototype property of Person?
OK. if we put ‘run’ to the constructor:
function Person(){
this.name = "Tom";
this.age = 23;
this.run = function(){
console.log(this.name+" is running! ");
}
}
It seems fine, right? Yes, it will produce the same result, but the problem is that this approach is not efficient. What I mean is that function ‘run’ will be redefined everytime when a new object is created, it does not share with other objects. But if we use prototype.run, then every object instance which inherits from Person will automatically have that function without redefinition.
Here are two links which are very good articles and a good answer from stackoveflow about ‘new’ keyword:
Two articles:
1. Learning JavaScript Design Patterns
–this is my favourite article, very good explanation about Javascript OOP and also good module pattern, helping us write good codes.
2. Object Oriented Programming in Javascript
–Good explanation about OOP, prototype, and how prototype chain works.
One good answer from Stackoverflow:
http://stackoverflow.com/questions/1646698/what-is-the-new-keyword-in-javascript/3658673#3658673
–I believe that is one of the best answer I’ve ever seen in Stackoverflow, precise and nice example