Understanding the JavaScript new keyword
From Trephine
| « JavaScript classes | Self-replicating JavaScript Objects » |
[subscribe] Recent blog entries
- Simple prototypal inheritance new!
- Adventures in Rhino - setters and getters
- Site improvements - fighting with Disqus
- JavaScript task chaining
- JavaScript string building benchmarks
- Efficient JavaScript string building
- Alternative JavaScript worker thread API
- Implementing JavaScript worker threads
- Thread safe DOM manipulation
- Site improvements - CSS sprites
- Trephine worker threads made easy
- Pitfalls of multithreaded browser development
- Site improvements - reducing dependencies
- The unsplittability of XML
Live Demos
Understanding the JavaScript new keyword
Yesterday's article talked about JavaScript classes, or more accurately, JavaScript's prototyping model. This article explores the depths of the new keyword, explaining exactly what it does under the covers.
For starters, let's begin with the Person example from yesterday:
function Person( name ) { this.name = name; }
The question is, what exactly happens when we create Person instances using new Person()? Consider bob, an instance of Person:
var bob = new Person( "Bob" );
Putting "new" in front of a function call is referred to as calling a function in a constructor context. When new Person( "Bob" ) is called, the JavaScript engine does the following:
- Creates a new empty
Object, - Sets an internal properety indicating that the empty object's prototype is
Person, - Prepares to execute the
Personfunction, passing in the empty object asthis, and the string"Bob"as thenameparameter, - Executes the function, which sets empty object's
nameproperty to"Bob", - Returns the object.
Finally, this object is assigned to the bob variable, at which point it becomes convenient to refer to it as "bob".
An interesting consequence of creating a function in JavaScript is that its prototype contains a property called constructor which points right back to the function itself. So for example:
Person.prototype.constructor == Person; // true
Now consider what happens if we try to grab bob.constructor. As explained in the JavaScript classes article, when an object is created from a function using the new keyword, property lookups for that object will bubble up as follows:
- Check for the property on the object itself,
- Check for the property on the prototype of the function from which the object was created,
- Check for the property on the
Objectprototype.
In this case, the "constructor" property is found on the Person prototype. That is:
bob.constructor == Person; // true
One interesting question is that given all of the above, could we emulate the behavior of the new keyword? The answer is "kinda", here is one attempt:
function factory( func ) { var obj = {}; var args = []; for (var i=1, l=arguments.length; i<l; i++) args[i-1] = arguments[i]; func.apply( obj, args ); obj.constructor = func; return obj; }
We could then call on the factory() to produce prototype instances like so:
var alice = factory( Person, "Alice" );
Aside from their name properties, the only differences between alice and bob are:
- bob's prototype is
Personwhereas alice's isObject -
bob.constructorfalls through to thePersonprototype whereasalice.constructoris a property on the object itself.
So, in essence, using the factory() function to create objects divests themselves of the prototype property inheritance chain, but maintains the constructor aspect. This could be good or bad depending on your particular application.
That's about all there is to it. I hope this helps you understand the JavaScript new keyword a little better.
Public domain declaration
Just so there's no confusion: all of the code snippets on this page are provided "AS IS", without warranty of any kind, express or implied.
All of the code snippets on this page are hereby released into the public domain by the me, the copyright holder. This applies worldwide. Or in case this is not legally possible: The copyright holder grants any entity the right to use this work for any purpose, without any conditions, unless such conditions are required by law.
If you'd feel better with a "real" license, you're free to use code snippets on this page under the MIT license as described on the about page.
Any links back to this site are always appreciated, but not required. Enjoy!
--Jim R. Wilson (jimbojw) 03:16, 8 April 2009 (UTC)