Closures, Javascript, and Objects - Part II
This is the second and briefer post of two on OOP in Javascript. Previously we covered object creation using the notion of closures and implicit object creation with the ‘{}’ syntax. Now we’ll cover more advanced object creation with prototypes and the new keyword.
In the prior post we created objects implicitly within the closure of an outer function. The enclosing function enabled us to initialize the new object and create a runtime environment for it. In creating a closure and runtime environment the outer function acted as a constructor of the created object.
The new keyword enables us to create a function that also acts as an object constructor. A function that creates an object using the new keyword is similar in form to the functions we used in Part I but with fewer lines of code. Here is an example rewritten from the last post to take advantage of new:
var c = function() {
this.x = 3;
this.y = 4;
this.f = function(z) { //map an anonymous function to the name f in the map obj
return this.x + this.y + z;
}
this.f2 = function(z) { //map another anonymous function to the name f2
return this.x - this.y - z;
}
}
var myObject = new c();
myObject.f(5) // = 12
myObject.f2(5) // = -6
The function c when used with the new keyword creates an object with the properties x, y, f, and f2. The new keyword’s behavior is very similar to what we got previously from using ‘{}’, but with less code. When the function c runs, ‘this’ refers to the newly created object that will be returned. It is as if we had used ‘{}’ to create an object and then manually assigned properties to it. One key note about constructor functions though, the function will break if called without the new keyword. When called without the new keyword the function operates normally and not like a constructor, in particular ‘this’ will no longer refer to a new object, but will likely refer to something in the context of the function. In short, calling the constructor without the new keyword will have unpredictable and undesired results.
Using the simpler object construction syntax we can harness prototypes to make our objects more efficient. Regarding prototypes – Javascript is not a class based object oriented language, instead Javascript is a prototyped based language.. While the prior statement has several implications, for now we can focus on the central concept of the prototype.
One way of thinking of prototypes is that they form the basis for an object to be constructed from. If an object, A’s prototype contains a member B, then we will be able to access B via A.B. A primary way to create objects in JS is to use another object, A as the new object, B’s prototype. Object B will inherit access to A’s members and we will also be able to modify B to have new members too. An example:
var c = function() {
this.x = 3;
this.y = 4;
this.f = function(z) { //map an anonymous function to the name f in the map obj
return this.x + this.y + z;
}
this.f2 = function(z) { //map another anonymous function to the name f2
return this.x - this.y - z;
}
}
var myObject = new c();
myObject.x // = 3
myObject.z // = null
var d = function() {
this.z = 1;
}
d.prototype = new c(); //sets the prototype for objects created by c
var myOtherObject = new d();
myOtherObject.x; // = 3
myOtherObject.z; // = 1
In the example above we use prototypes to create an inheritance from object c to d. An important take away is that the new keyword sets a created object’s prototype to the value of the prototype property of the constructor function. By setting the prototype property of constructor functions we can create object inheritance hierarchies in JS. Speaking about inheritance hierarchies is the subject of another post for the future, for now let it suffice to say that it is another important component of OOP.
This post serves as a short and simple introduction to prototypes and new in JS. I kept my words brief because there is already a wealth of well written information on the subject available at the following links:
- On the prototype property and inheritance - I particularly like the Q&A style that this post is written in.
- On just prototypes with several examples
- A more general overview of OOP in JS