For those of us that are used to “Newing up an object” from traditional class based languages, the way the new
keyword works in JavaScript can be confusing. In class based languages, we have a class that acts as a blueprint and when we want an object of that class to work with, we are said to instantiate that class. So traditionally, objects come from classes. JavaScript has no such mechanism. Although JavaScript has objects, they do not come from classes. This short tutorial will be a quick overview of the four things that happen when you use the new
keyword in JavaScript. With new
in JavaScript, you are making a Function Call, not instantiating an object from a class. When you call a function with the new
keyword, four important things happen. Let’s go over them now.
When you use the new
keyword in JavaScript…
-
1. A Brand New Object Gets Created
-
2. The Created Object Gets [[Prototype]] linked
-
3. The Created Object is set to
this
for that function call -
4.
this
(the newly constructed object) is automatically returned from the new-invoked function, unless it explicitly returns a different object
Now first off, in order to call a function using the new
keyword, we must actually have a function declaration to work with. With that in mind, let’s define a function in JavaScript.
1 2 3 |
function House(color) { this.color = color; }; |
Ok, we have a simple function named House
. It accepts a parameter of color
, and assigns it to it’s own color property. Let us now call that function using the new
keyword.
1. A New Object Is Created
1 |
var HouseOne = new House('Red'); |
Poof! As if by magic, the variable HouseOne
is now a new object. How do we know? Observe.
1 |
console.log(typeof HouseOne); // object |
You did not instantiate any type of class whatsoever. All you did was call a function, and again, as if by magic, a brand new object was created and returned to you in one step.
The second thing that happens is that the new object gets [[Prototype]] linked. Just what does that mean? It means that HouseOne
has a prototype linkage to House.prototype
. Let’s see how this works in code.
2. Created Object Gets [[Prototype]] linked
We have a function named House
, which is about as bare bones as they come. It has one property, color
. It has no methods, no functionality, not much of anything. We are going to call a method on our newly created object called whatcolor()
. This method will simply log a message indicating what color the newly created house is. Now pay attention, as we are not going to touch our original constructor function, but we will see the whatcolor()
method work!
1 2 3 4 5 6 7 |
function House(color) { this.color = color; }; House.prototype.whatcolor = function () { console.log('The color of this house is ' + this.color); }; |
1 2 |
HouseOne.whatcolor(); // The color of this house is Red |
The whatcolor()
method worked only because HouseOne
has a prototype linkage to House.prototype
. So we can see that using the new
keyword does create this prototype linkage automatically for us. This is how we do inheritance in JavaScript. It makes sense to refer to it as inheritance, since that is what we are used to in traditional object oriented languages. What is really happening here though, is that JavaScript is delegating the function call of whatcolor()
up the prototype chain. It works almost like lexical scoping, where if JavaScript does not find the variable in the local scope, it will move one step outside of the local scope and look for a particular variable there. With function calls, it works in a similar way. House
tries to call the whatcolor()
function, notices that it does not have a whatcolor()
function, then sends the request up the prototype chain. It turns out House.prototype
does in fact have that function, so alas, it does the function call for us. Code reuse in JavaScript happens via a bottom to top sequence of delegation, whereas what we are all familiar with is a top / down sharing via inheritance in classical object oriented programming. The end result is similar, but the internal processes in the language are very different. Let us now take a look at the third thing that happens when you use the new
keyword on a function in JavaScript.
3. The brand new object that was created gets bound to this
for the purposes of that function call.
As we know, during the call of a function by use of the new
keyword, a new object is created. Within the function that was called, this
now refers to the newly created object. Learn all about the JavaScript this Keyword if you are not familiar. Let’s see this third rule in action now.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
function House(color) { this.color = color; }; House.prototype.whatcolor = function () { console.log('The color of this house is ' + this.color); }; var HouseOne = new House('Red'); var HouseTwo = new House('Blue'); HouseOne.whatcolor(); // The color of this house is Red HouseTwo.whatcolor(); // The color of this house is Blue |
The reason why we get the right color back in the example above is because of the this
binding. We call the House
function two times with the new
keyword. In the first instance, this
points to the first object we created via new House('Red');
. In the second instance, this
points to the second object created in our program via var HouseTwo = new House('Blue');
. Finally, we can examine how this
is automatically returned if there is no other object being returned from that function call.
4. this
(newly created object) is returned
The best way to illustrate this is to look at two different function definitions. The first one has no return statement. In that case, if the new
keyword is used to call that function, that function will return this
(which as we know, is the newly created object). Let’s see it now:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
function House(color) { var obj = { color: 'Green' }; this.color = color; }; var HouseOne = new House('Red'); console.log(HouseOne.color); // Red console.log(HouseOne instanceof House); // true |
The function returns this
, the newly created object. We proved this by checking if HouseOne
is an instance of House
, and we do get true
. Let us now simply change the function ever so slightly by adding a return
statement to it.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
function House(color) { var obj = { color: 'Green' }; this.color = color; return obj; }; var HouseOne = new House('Red'); console.log(HouseOne.color); // Green console.log(HouseOne instanceof House); // false |
As we can see here, the returned object is now no longer an instance of House
! It is simply a plain JavaScript object returned from that function call. So we can see, when using the new
keyword on a function in JavaScript, you will get different results based on whether that function explicitly returns an object or not. JavaScript!
Four Things That Happen When The JavaScript new
Keyword Gets Called With A Function Call Summary
The behavior of the new
keyword in JavaScript is insane. This article is as much to help the author, as it is to help the reader. In order to use JavaScript effectively, or even be able to read source code with understanding, you need to really understand how new
and this
work. What makes this difficult is that most of us start programming JavaScript and expect new
to instantiate an object from a class, like Java or PHP. In JavaScript, new
has nothing to do with classes. It has nothing to do with instantiating objects from classes. In fact, JavaScript has no classes. In JavaScript, new
magically turns any function it is used on into a constructor call. This still does not have anything to do with classes! In addition to that, new
modifies the behavior of the typical JavaScript function call in four distinct ways which we covered above. Hat tip to getify for helping clear things up with regard to new
and this
!