Close
Glad You're Ready. Let's Get Started!

Let us know how we can contact you.

Thank you!

We'll respond shortly.

LABS
JavaScript constructors, prototypes, and the `new` keyword

Are you baffled by the new operator in JavaScript? Wonder what the difference between a function and a constructor is? Or what the heck a prototype is used for?

I’m going to lay it out straight.

Now, there’s been a lot of talk for a long time about so-called “pseudo-classical” JavaScript. Mostly, the new guard of JavaScript folk don’t like to use the new keyword. It was written into the language to act more like Java, and its use is a little confusing. I’m not going to take sides here. I’m just going to explain how it works. It’s a tool; use it if it’s practical.

What is a constructor?

A constructor is any function which is used as a constructor. The language doesn’t make a distinction. A function can be written to be used as a constructor or to be called as a normal function, or to be used either way.

A constructor is used with the new keyword:

var Vehicle = function Vehicle() {
  // ...
}

var vehicle = new Vehicle();

What happens when a constructor is called?

When new Vehicle() is called, JavaScript does four things:

  1. It creates a new object.
  2. It sets the constructor property of the object to Vehicle.
  3. It sets up the object to delegate to Vehicle.prototype.
  4. It calls Vehicle() in the context of the new object.

The result of new Vehicle() is this new object.

1. It creates the new object.

This is nothing special, just a fresh, new object: {}.

2. It sets the constructor property of the object to Vehicle.

This means two things:

vehicle.constructor == Vehicle  // true
vehicle instanceof Vehicle      // true

This isn’t an ordinary property. It won’t show up if you enumerate the properties of the object. Also, you can try to set constructor, but you’ll just set a normal property on top of this special one. To wit:

vehicle;                          // {}

var FuzzyBear = function FuzzyBear() { };
vehicle.constructor = FuzzyBear;

vehicle;                          // { constructor: function FuzzyBear() }
vehicle.constructor == FuzzyBear; // true
vehicle instanceof FuzzyBear      // false
vehicle instanceof Vehicle        // true

The underlying, built in constructor property is something you can’t set manually. It can only be set for you, as part of construction with the new keyword.

3. It sets up the object to delegate to Vehicle.prototype.

Now it gets interesting.

A function is just a special kind of object, and like any object a function can have properties. Functions automatically get a property called prototype, which is just an empty object. This object gets some special treatment.

When an object is constructed, it inherits all of the properties of its constructor’s prototype. I know, it’s a brainful. Here.

Vehicle.prototype.wheelCount = 4;
var vehicle = new Vehicle;
vehicle.wheelCount;         // 4

The Vehicle instance picked up the wheelCount from Vehicle‘s prototype

Now this “inheritance” is more than simply copying properties to the new objects. The object is set up to delegate any properties which haven’t been explicitly set up to its constructor’s prototype. That means that we can change the prototype later, and still see the changes in the instance.

Vehicle.prototype.wheelCount = 6;
vehicle.wheelCount;         // 6

But if we like, we can always override it.

vehicle.wheelCount = 8;
vehicle.wheelCount          // 8
(new Vehicle()).wheelCount  // 6;

We can do the same thing with methods. After all, a method is just a function assigned to a property. Check it.

Vehicle.prototype.go = function go() { return "Vroom!" };
vehicle.go();                              // "Vroom!"

4. It calls Vehicle() in the context of the new object.

Finally, the constructor function itself is called. Inside the function, this is set to the object we’re constructing. (Why? Because that’s what Java does.) So,

var Vehicle = function Vehicle(color) {
  this.constructor;       // function Vehicle()
  this.color = color;
}

(new Vehicle("tan")).color;   // "tan"

Side note: Above, I said the use of the new keyword returned the constructed object. This is correct unless the constructor returns something explicitly. Then that object is returned, and the constructed object is just dropped. But really. JavaScript slaves over a hot CPU to create this object for you and then you just throw it away? Rude. And confusing to people who use your constructor. So unless you have a really good reason, don’t return anything from constructor functions.

Putting it all together

Given this tool, here’s one way (the intended way, but not the only way) to implement something like classes in JavaScript.

// Class definition / constructor
var Vehicle = function Vehicle(color) {
  // Initialization
  this.color = color;
}

// Instance methods
Vehicle.prototype = {
  go: function go() {
    return "Vroom!";
  }
}

“Subclassing”

This “pseudoclassical” style doesn’t have an exact way to make subclasses, but it comes close. We can set the prototype of our “subclass” to an instance of the “superclass”.

var Car = function Car() {};
Car.prototype = new Vehicle("tan");
Car.prototype.honk = function honk() { return "BEEP!" };
var car = new Car();
car.honk();             // "BEEP!"
car.go();               // "Vroom!"
car.color;              // "tan"
car instanceof Car;     // true
car instanceof Vehicle; // true

Now, there’s a problem here. The Vehicle constructor only gets called once, to set up Car‘s prototype. We need to give it a color there. We can’t make different cars have different colors, which is not ideal. Some JavaScript frameworks have gotten around this by defining their own implementations of classes.

And for my last trick…

Sometimes you don’t want a notion of classes. Sometimes you just want one object to inherit the properties of another (but be able to override them). This is how most prototype-based languages work, but not JavaScript. At least, not without a little massaging.

This function lets us accomplish it. It’s been tossed around for a long time and is sometimes called “create” and sometimes “clone” and sometimes other things.

function create(parent) {
  var F = function() {};
  F.prototype = parent;
  return new F();
}

var masterObject = {a: "masterObject value"}

var object1 = create(masterObject);
var object2 = create(masterObject);
var object3 = create(masterObject);
var object3.a = "overridden value";

object1.a; // "masterObject value"
object2.a; // "masterObject value"
object3.a; // "overridden value"

masterObject.a = "new masterObject value"

object1.a; // "new masterObject value"
object2.a; // "new masterObject value"
object3.a; // "overridden value"

You said a mouthful.

The JavaScript prototype chain is a little different than how most languages work, so it can be tricky understand. It doesn’t make it any easier when JavaScript gets syntax that makes it looks more like other languages, like inheriting Java’s new operator. But if you know what you’re doing, you can do some crazy-cool things with it.

Comments
  1. Good stuff. These are JavaScript fundamentals, but a lot of people write a significant amount of JavaScript without ever being aware of any of this. Not to say they can’t skin the cat some other way, but you can write some clean sexy code using this knowledge.

    I’m curious what you think about this general method of JS inheritance that I created as a Frankenstein of the Crockford and MDC recommendations.

    http://brokenliving.blogspot.com/2009/09/simple-javascript-inheritance.html

    Maybe there’s an even better way, and if so I’d like to know it.

  2. Peter Jaros says:

    Ooh, that looks nice!

  3. […] However, there is a little flaw in some of the Javascript plugins: they don’t have a callback function. Luckily, doing some research on internet, a callback function can be added through the function property “prototype”. […]

  4. Olegs Klujs says:

    Thanks, it helpt me a lot.

  5. Aamir Afridi says:

    Thanks for explain everything in such a clear way.

  6. Javed Akhter says:

    Ooh, that’s very sharp and clean way! It helped me a lot.

  7. Perminder says:

    Loved the explanation….cleared a lot of ambiguities..thanks

  8. Minal Gandhi says:

    such great explanation….
    I like it…..!!

  9. Peter Alfvin says:

    As discussed on http://stackoverflow.com/questions/17118956/clarifying-javascript-prototype-nomenclature-and-mechanism, I believe this post is misleading and that Kyle Simpson’s comment is basically correct, the Chrome browser’s implementation of console.log notwithstanding. Although I gather the author has left the company, it would be nice if this post could be amended or removed (or this comment and Kyle Simpson’s comment rebutted).

  10. Al says:

    What is the advantage of using a prototype instead of defining the instance methods from within the constructor. For example, how is

    // Class definition / constructor
    var Vehicle = function Vehicle(color) {
    // Initialization
    this.color = color;
    }

    // Instance methods
    Vehicle.prototype = {
    go: function go() {
    return “Vroom!”;
    }
    }

    different from

    // Class definition / constructor
    var Vehicle = function Vehicle(color) {
    // Initialization
    this.color = color;
    this.go = function() {
    return “Vroom!”;
    }

  11. Colin Wood says:

    Al, I may be wrong here but I think the reasoning for not including instance methods inside the constructor is that doing so causes a function to be created for each instance, leading to lots of duplicated functions in memory. Defining the methods on the prototype leads to only one method which is shared by all instances, thus reducing duplicated code. Inside the instance method you can use ‘this’ to reference the individual instance.

  12. Vasan says:

    Great comment Colin. I would add that:
    1. Using prototype allows access to Super methods. Super methods can be accessible like this:
    object.prototype.functionA – will access finctionA from the Superclass.
    object.functionA – will access functionA in the same instance, and if not there, then will access that functionA from the Superclass

    1. ‘prototype’ is a property and by overriding it, you can created objects with properties defined in the constructor and properties from the prototype of an entirely different object.

  13. Simon Mather says:

    Excellent write up, clear and simple

  14. Martin says:

    That was a very good, clear and concise explanation thank you. This topic can be pages long in discussion, but I think you nailed it!

  15. Hito says:

    Could you tell me that why a Instantiated object has no prototype propertype?
    Like

    function Human(){
    this.name=”Dvida”;
    this.email=”xxx@xxx.xxx”;
    }
    var me=new Human();
    console.log(me.prototype);//undefined

    But a function created by new Function() has the prototype propertype
    like

    var poly=new Function();
    console.log(poly.prototype);//Object {}

    Thanks very much!

  16. pete says:

    @Kyle Simpson:

    You said “If you make your own objects and use them as a constructor’s `.prototype`, they won’t be default have a `.constructor` property added to them,” but I tried I could not confirm this is true, what am I missing here:

    function Test() {}
    Test.prototype = {};
    var object1 = new Test();
    console.log(object1.constructor);

    @Hito: prototype is a property of functions, so instead of:
    console.log(me.prototype);//undefined
    you can do:
    console.log(Human.prototype);

    Also poly is a function that’s why it has prototype.

    See how the article explains this “A function is just a special kind of object, and like any object a function can have properties. Functions automatically get a property called prototype, which is just an empty object. This object gets some special treatment.”

  17. Aidan says:

    Thanks, very interesting and easy to understand. This is a must read for JS developers. Keep posting cool stuff like this!)

  18. Ali Alavi says:

    Very nice article. I am new to JavaScript / Angular and this article resolved good chunk of confusion I had about object creation/function/inheritance/… . Thank you very much for sharing your knowledge in such a nice and easily-understandable write-up.

  19. Wing says:

    Nice article, but one thing, `new Class()` will NOT sets the `constructor` property to `Class`, we can get the `constructor` because it set the `__proto__` to `Class.prototype` see this:

    function C() {}
    c = new C();
    Object.getOwnPropertyNames(c)
    // []
    Object.getOwnPropertyNames(a.__proto__)
    // [“constructor”]

  20. Love this post, helped big time to understand the new() keyword. Pretty awesome stuff.

    I do have one correction:

    “2. IT SETS THE CONSTRUCTOR PROPERTY OF THE OBJECT TO VEHICLE.
    This means two things:

    vehicle.constructor == Vehicle // true
    vehicle instanceof Vehicle // true”

    the second part of this is not true. vehicle instanceof Vehicle does not use the .constructor property.

    instanceof compares the object’s __proto__ to the object your checking’s .prototype.

    To show the point here:

    var s = new String();
    s.constructor == String // => true
    s instanceof String // => true
    s.constructor = “New value”
    s.constructor == String // => false
    s instanceof String // => true

    “vehicle instanceof Vehicle // true” this part of your post should be moved to #3, the delegation of .prototype

  21. Jainil Dodia says:

    You mentioned that it creates a constructor property on the newly created object which is not true. The contructor property is actually present on the prototype object itself even before the new keyword was called.

Post a Comment

Your Information (Name required. Email address will not be displayed with comment.)

* Copy This Password *

* Type Or Paste Password Here *