Coming from the PHP world, I've spent a lot of time trying to reproduce or finding a similar way to work with objects and inheritance with Javascript. A lot of libraries gives you their own style of a class-like functionality with javascript, and yes, it will work similarly as OO classes, but after a big javascript project, you will probably want to understand what's all this prototype stuff appearing in your console during your debug sessions, and eventually find out that the classical inheritance and its preferred keyword new does not suit javascript so well.

Forget about “new”

The first thing that confuses developer that really start developing with javascript is the new keyword. “ah ok, like in PHP or Java, I can create instances of Car with new Car(), easy”. I won't dive into [history details] here, but you have to know that new was only introduced to let javascript gain more popularity. new is syntactic sugar, but hides the real prototypal nature of the language.

Check the following constructor pattern in javascript:

function Rectangle(width, height) {
  this.height = height;
  this.width = width;
}

Rectangle.prototype.area = function () {
  return this.width * this.height;
};

var rect = new Rectangle(5, 10);
alert(rect.area());

It looks not so bad. Well I have to use this prototype keyword there, but ok, if it works like that. Let's define a square now, which is kind of a rectangle, so it extends our Rectangle class:

function Square(side) {
  return Rectangle.call(this, side, side);
}

Square.prototype = new Rectangle(); // yes, no arguments
Square.prototype.constructor = Square; // fix, otherwise it points to Rectangle

var sq = new Square(5);
alert(sq.area());

It become quite complicated to explain what we are doing here, we have to play a lot with this 'prototype' property, and this is not intuitive at all.

'Object.create' is your friend

Forget the constructor stuff, we have to think differently, with objects, and you will eventually find out that there is not much to know to build whatever you want: in javascript, objects inherit from other objects, and that's what you do when you want a new instance inheriting from another: create a new object 'B' and tell it to inherit this other object 'A'. All the properties of 'A' will be available in the new object, and you can override them if you want to.
Let's take our previous example with Rectangle and Square and rewrite it:

var Rectangle = { // just an object
  width: 0,
  height: 0,
  area: function() {
    return this.width * this.height;
  }
};

var rect1 = Object.create(Rectangle); // create a new object, extend it from Rectangle
rect1.width = 10;
rect1.height = 5;
alert(rect1.area());

Isn't that much clearer? Object.create is a native javascript function in ECMAScript 5, compatible in all major browsers (there is a polyfill for old browsers). The argument it takes is the object we want to extend (it can take a second one but I won't talk about it in this post). The way to define width and height is not so nice though, let's create kind of a constructor:

var Rectangle = {
  create: function(width, height) {
    var newObj = Object.create(this); // create a new object based on itself
    newObj.width = width;
    newObj.height = height;

    return newObj;
  },
  area: function() {
    return this.width * this.height;
  }
};

var rect1 = Rectangle.create(10, 5);
alert(rect1.area());

create is kind of a factory (avoid the term constructor now), and what's nice is that it's integrated in the object itself.

Let's create the square now:

var Square = Object.create(Rectangle); // extend Rectangle
Square.create = function(side) {
  // take the create function of Rectangle, or do something totally different
  return Rectangle.create(side, side);
}

var sq = Square.create(10);
alert(sq.area());

This is so more intuitiv: Square is a base object, once defined you don't want to touch it (except if you want to modify all square instances). Then you create an instance of it by calling Square.create. Note that we didn't have to use the prototype keyword to achieve inheritance.

What's behind

Let's have a look at the sq object in the console:

Details of a square instance

We can see that the properties of Rectangle are in __proto__, and width and height are own properties of the object. If the object doesn't redefine its properties, the javascript engine will look for them in __proto__, and if it doesn't find them, will dive deeper into __proto__ of __proto__, until it finds it (or an exception is thrown). So by nature, javascript has this inheritance chaining built-in, and there lies all the power of the language.

By the way you maybe also noticed that the very last __proto__ contains some basic functions: all objects in javascript inherit from Object and therefore have these native functions like valueOf or toString.

Beware of references

Because the objects extend other objects, you have to keep in mind that some properties of your object are in __proto__, and therefore were not copied when you created your instance. This can lead to unexpected behaviour if you forget about it, let's see an example:

var CarOption = {
  create: function(name, price) {
    var newOption = Object.create(this);
    newOption.name = name;
    newOption.price = price;

    return newOption;
  }
};

var Car = {
  type: 'car',
  options: [],
  addOption: function(option) {
    this.options.push(option);
  }
};

var leatherOption = CarOption.create('leather', 200);
var metallicOption = CarOption.create('metallic paint', 600);

var luxuriousCar = Object.create(Car);
luxuriousCar.addOption(leatherOption);
luxuriousCar.addOption(metallicOption);
console.log(luxuriousCar.options.length); // 2 options, ok

var poorCar = Object.create(Car);
console.log(poorCar.options.length); // 2 options too!

poorCar has 2 options too because both instances have their options property pointing to the base Car.options property. To fix it, you have to create an options array whenever you create a car instance. Let's add a create function to do this:

var Car = {
  type: 'car',
  create: function() {
    var newCar = Object.create(this);
    newCar.options = []; // give it its own options array

    return newCar;
  },
  addOption: function(option) {
    this.options.push(option);
  }
};

var luxuriousCar = Car.create(Car); // use our new factory
luxuriousCar.addOption(leatherOption);
console.log(luxuriousCar.options.length); // 1 option, ok

var poorCar = Car.create();
console.log(poorCar.options.length); // 0 options, ok

Having properties in common can be very useful though, if I change the type property of Car, all the instances will get the new type.

Conclusion

Javascript requires another way of thinking, where Objects are first-citizen and can construct or be constructed easily, without the need for a new keyword.

Create a base object, extend from it, extend from others, change its behaviour, the language let you do nearly everything, leading to a lot of flexibility, but also to multiple way of doing things (which is not always good for developer, often looking for the right way to do what they intend to do).

Of course new has sometimes legitimate uses, and does not really cause problems if you don't need inheritance. But are you really wanting to use it now that you read this?