Self-executing functions

September 15th, 2009

Update: "Immediate functions" sounds like a much better name.

Self-executable functions are simple and powerful.

All you do is add a set of parentheses after the function and this causes it to be executed right there. If it’s an anonymous function you also need to wrap it in parentheses.

(function(){
   var a = 1;
   var b = 2;
   alert(a + b);
})();

You can also pass parameters to the self-executing function if you want.

(function(a, b){
  var c = a + b;
  alert(c);
})(1, 2);

So how is this pattern useful?

It’s useful when you have some work to do, some initialization maybe. You need to do it only once and you don’t want to leave any globals lying around after the work is finished. All the temporary variables you need like c in the case above remain local and don't pollute the namespace.

Useful also when your code is kind of a guest to the page. Like a bookmarklet for example, or a widget of some sorts. You don’t want to add your variables and functions to the host page’s naming space and possibly causing a naming conflict with the page's core code.

Functions are objects

September 15th, 2009

Functions are objects, it’s very important to keep that in mind.

Functions are objects so they can have properties. And they they have methods.

They can be copied, deleted, passed as arguments to other functions, returned by other functions.

They also provide scope.

And they have special feature that sets them apart from the other objects – they are invokable, they can be called.

Prototypal inheritance

September 15th, 2009

Here's the prototypal inheritance pattern suggested by Douglas Crockford.

The implementation looks similar to a classical pattern but the idea is very different.

The idea is that there’s no constructors involved that lead you to think in terms of classes.
You have an object and you want to create another object that gets functionality from the existing object.

And, unlike when we simply copied properties over from the parent, here we involve the prototype and keep the prototype chain.

function object(o) {
  function F(){}
  F.prototype = o;
  return new F();
}

We take an existing object o, create a blank constructor function and set the parent object o to be the prototype.

Then return an object created with the temporary constructor. This child object has all properties of the parent as part of the prototype.

And here’s an example usage:

>>> var parent = {a: 1};
>>> var child = object(parent);
>>> child.a;
1
>>> child.hasOwnProperty(a);
false

The child object has everything the parent has - not as its own properties but as properties of its prototype.

ECMAScript 5

In the proposed version 5 of the ECMAScript standard, there will be a method that will work similarly and also accept another object, so basically you'll be able to inherit and add more functionality at the same time.

var child = Object.create(parent, {more:1})

Classical inheritance

September 15th, 2009

Let's talk a bit about classical inheritance. The word "classical" is not used in the sense of old-school middle-age has-been-around forever kind of meaning.

Classical just means that you think in terms of classes. Your objects are created by constructor functions and you want objects created from one constructor Child() to get properties that come from another constructor Parent().

function Parent(){
  this.name = 'Adam';
}
Parent.prototype.say = function(){
  return this.name;
};
 
function Child(){}

So we call a function called inherit() and let’s see some patterns for implementing this function.

inherit(Child, Parent);

Option #1 - The ECMA way

Here's the ECMA standard way. You create an object using the Parent() and assign this object to the Child()'s prototype.
Than when you do new Child(), it will get functionality from the Parent() instance via the prototype.

function inherit(C, P) {
  C.prototype = new P();
}

This pattern has the drawback that it’s tough to pass arguments to the parent during the call to new Child()

Option #2 - Rent-a-constructor

This next pattern solves the problem of passing arguments. It borrows the parent constructor passing the child object to be bound to this and passing any arguments.

This way you can only inherit properties added to this inside the parent constructor.
You don't inherits stuff that was added to the prototype.

function C(a, c, b, d) {
  P.call(this, arguments);
}

Option #3 - rent + prototype

Combining the previous two patterns you can pass arguments by borrowing the constructor and also inherit from the prototype.

function C(a, c, b, d) {
  P.call(this, arguments);
}
C.prototype = new P();

Drawback is that the parent constructor is called twice.

Option #3

Here's another way to do classical inheritance that doesn't include calling the parent constructor at all.

The rule of thumb is that reusable stuff should go to the prototype.

So for inheritance purposes, anything interesting should be in the prototype. Can you just say that child’s is the parent’s prototype? Yes, you can.

function inherit(C, P) {
  C.prototype = P.prototype;
}

This gives you really short prototype chain lookups because everybody has the same prototype. But that’s also a drawback because if a child down the inheritance chain modifies the prototype, it affects all parents.

Option #5

This next pattern solves the same-prototype problem by breaking the direct link and benefiting from the prototype chain.

Here you have an empty function which gets the prototype of the parent. The prototype of the child is an instance of the blank function.

function inherit(C, P) {
  var F = function(){};
  F.prototype = P.prototype;
  C.prototype = new F();
}

This pattern has a behavior slightly different from the ECMA standard suggestion because here you only inherit properties of the prototype. And that’s fine, actually preferable. Like I said – the prototype is the place for reusable functionality. Anything the parent ads to this inside the constructor is ignored.

Option #5 + super

Building on top of the previous pattern, you can add a reference to the original parent. This is like having access to the superclass in other languages.

The property is called uber because super is a reserved word and superclass may lead the non-suspecting developer down the path of thinking that JavaScript has classes. And we don’t want that, right?

function inherit(C, P) {
  var F = function(){};
  F.prototype = P.prototype;
  C.prototype = new F();
  C.uber = P.prototype;
}

Option #5 + super + constructor reset

One last thing to do in this almost perfect classical inheritance function is to reset the pointer to the constructor function in case we need it down the road.

function inherit(C, P) {
  var F = function(){};
  F.prototype = P.prototype;
  C.prototype = new F();
  C.uber = P.prototype;
  C.prototype.constructor = C;
}

If you don’t reset the constructor pointer, objects created with the Child() constructor will report that they were created with the Parent() constructor.

A function like this exists in the YUI library and helps you with your classical inheritance needs.

Mixins

September 15th, 2009

Taking the idea of inheritance by property copying a step further, consider this this mixin implementation.

Instead of copying from one object, you can copy from any number of objects.

The implementation is pretty simple - just loop through arguments and copy every property of every object passed to the function.

function mixInThese() {
  var arg, prop, child = {};
  for (arg = 0; arg < arguments.length; arg++) {
    for (prop in arguments[arg]) {
      child[prop] = arguments[arg][prop];
    }
  }
  return child;
}

Here's how to use it. Pass any number of objects and you and up with a new object that has the properties of them all.

var cake = mixInThese(
 {eggs: 2, large: true}, 
 {butter: 1, salted: true}, 
 {flour: "3 cups"},
 {sugar: "sure!"}
);

Inheritance by copying properties

September 14th, 2009

Let's take a look at an inheritance pattern – inheritance by copying properties. In this pattern an object gets functionality from another object, simply by copying it.

function extend(parent, child) {
  var i, child = child || {};
  for (i in parent) {
    child[i] = parent[i];
  }
  return child;
}

In this implementation child is optional, if you don't pass an existing object to augmented, than a brand new is created and returned.

It's a very simple implementation, just looping through the parent’s members and copy them over.

Now you may say "Hey, hey, hey, what about performance? Isn’t it inefficient to copy around properties like this?". Technically yes, but if that’s your performance bottleneck, you probably have the fastest JavaScript app ever.

This works for many applications, Firebug has an extend() methods that does this. Firebug is a pretty complex app and this works for it, so it should work for many other applications.

And one more heads-up - this is a "shallow copy" of the object, if you need you can do a "deep copy" - checking if the property you're about to copy is an object and if so, recursively iterate through the properties.

Borrowing methods pattern

September 14th, 2009

Functions in JavaScript are objects, they come with some cool methods of their own, like call() and apply(). The only difference between both is that one takes an array of parameters, the other one takes parameters one by one.

And you can use these methods to borrow functionality. Here's how:

// call() example
notmyobj.doStuff.call(myobj, param1, p2, p3);
// apply() example
notmyobj.doStuff.apply(myobj, [param1, p2, p3]);

So your object is called myobj and you know some other object called notmyobj has an extraordinary useful method called doStuff().
Instead of going through the inheritance hassle and inherit a bunch of stuff you don’t need, you can simply borrow the method you like temporarily.

You pass your object and any parameters and the other binds your object as its own this. Basically you pretend to be the other object, benefit from the method you like and move on.

It’s like getting an inheritance but without paying the inheritance tax. Where tax that comes in the form of useless properties.

Example: borrow from Array

A common use for this pattern is borrowing array methods.

Arrays have useful methods which array-like objects such as arguments do not. So arguments can borrow methods, like the slice() method.

function f() {
   var args = [].slice.call(arguments, 1, 3);
   return args;
}
 
// example
f(1, 2, 3, 4, 5, 6) // return [2,3]

In the example above, there’s an empty array created just for the sake of using its method.
A slightly longer way to do the same is to borrow the method from the Array.prototype directly. This saves creating one empty array.

Array.prototype.slice.call(...)

A case against inheritance

September 14th, 2009

Provocative title, right? Good. The point is not that inheritance is all that bad, it's that you should stop and think or a moment before you jump into long inheritance chains and complex UML.

In fact, the Object-Oriented Design Patterns book from "the gang of four" has this to say about inheritance:

“Prefer object composition to class inheritance”

It’s pretty easy to follow this advice in JavaScript. Remember - no classes in JavaScript. And how about the object literal, how simple it is? If you can add functionality to your objects from elsewhere – why do you need inheritance.

You can start with a blank slate and add stuff – either implement it yourself or grab from someone else.

Keep your eyes on the prize. You don’t need inheritance, you need functionality. In other languages inheritance may be your only choice. Not in JavaScript.

Further blog posts will show patterns such as borrowing methods, copying properties, mixins...

Prototype

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

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