Posts Tagged ‘constructors’

Prototype

Monday, September 14th, 2009

The prototype is an object that every function gets automatically, as soon as you create it.

You can add properties and methods to the prototype property of your constructor function. Then all objects created with this constructor will have access to everything you add to the prototype.

var Person = function(name) {
  this.name = name;
};
Person.prototype.say = function() {
  return this.name;
};

if you add properties to the prototype of a "normal" function, meaning function that you don't invoke as a constructor, these will not be used.

Using the prototype

var adam = new Person('Adam');
alert(adam.name); // "Adam"
alert(adam.say()); // "Adam"

As you can see the object has access to the prototype’s members.

The prototype properties are shared among all objects.

Rule of thumb

And a general rule of thumb – the properties and methods that are meant to be reused and shared and inherited, should be added to the prototype.

Enforcing `new` in constructors

Monday, September 14th, 2009

A constructor is just a function and failing to invoke a constructor with new leads to errors. Not syntax errors but logical errors. Following a naming convention can certainly help, but it doesn't enforce the correct behavior. If you invoke a constructor without new, then this will refer to the global object, called window in browsers.

Here's a pattern that helps you make sure your constructor always behaves as constructor. Instead of adding all members to this, you add them to that.

In this implementation that is the same as this unless this is window which means someone forgot to use new.

function Person() { 
  var that = (this === window) ? {} : this;
 
  that.name = name;
  that.say = function() {
    return "I am " + that.name;
  };
 
  return that; 
}

window is only in browsers

Another way, if you work in non-browser environment is to check if this is an instance of your Person constructor.

Or name-agnostic, general-purpose way is to use arguments.callee instead of hard-coding the constructor name.

this instanceof Person
this instanceof arguments.callee

Constructor naming convention

Monday, September 14th, 2009

Constructors are just functions, it all depends on how they are invoked - with or without new.

So a naming pattern is pretty useful to help you visually distinguish between the two. It gives you a clue that the uppercase functions are meant to be called with new.

MyConstructor
myFunction

Constructors

Monday, September 14th, 2009

A simple way to create objects in JavaScript is using object literal notation. An other way, a bit more involved is to use a constructor function.

var adam = new Person("Adam");
adam.say(); // "I am Adam"

The invocation of the constructor looks a bit like a class in other languages, but the constructor is still just a function. (JavaScript doesn’t have classes). So the constructor is the blueprint, the recipe for the object.

And here's how the constructor Person is defined, it adds all members to the this object.

var Person = function(name) {
 
  this.name = name;
  this.say = function() {
    return "I am " + this.name;
  };
 
};

When you define a constructor, something like the following happens behind the scenes. It's as if you defined an object using the literal notation and then returned it.

var Person = function(name) {
  // var this = {};
  this.name = name;
  this.say = function() {
    returnI am ” + this.name;
  };
  // return this;
};