Understanding the JavaScript new keyword

From Trephine

Jump to: navigation, search
« JavaScript classes Self-replicating JavaScript Objects »

[subscribe] Recent blog entries

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:

  1. Creates a new empty Object,
  2. Sets an internal properety indicating that the empty object's prototype is Person,
  3. Prepares to execute the Person function, passing in the empty object as this, and the string "Bob" as the name parameter,
  4. Executes the function, which sets empty object's name property to "Bob",
  5. 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:

  1. Check for the property on the object itself,
  2. Check for the property on the prototype of the function from which the object was created,
  3. Check for the property on the Object prototype.

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:

  1. bob's prototype is Person whereas alice's is Object
  2. bob.constructor falls through to the Person prototype whereas alice.constructor is 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)