Welcome to AboutHalf

menu - http://abouthalf.com







If you have leftover boneless chicken thighs, UNDER NO CIRCUMSTANCES should you cut those thighs into 1/2″ strips, season them lightly with kosher salt, pan fry them in olive oil, then toss them in equal parts butter and your favorite hot sauce, and then toss in some bleu cheese crumbles.

And ONE SHOULD NEVER put this mixture onto thick sliced, toasted bread and call it a buffalo chicken salad sandwich.

Buffalo chicken salad?


Understanding Class.js

If you do any serious JavaScript development you’ve probably run across John Resig’s “Simple JavaScript Inheritance” article detailing Class.js, a small library for simulating a classical inheritance in JavaScript.

It’s an elegant bit of code, powerful but small. When I was first learning JavaScript deeply, I pored over this article and the code, line by line, until I understood it thoroughly. That proved to be a good exercise. Every once in a while I go through it again as a refresher.

Class.js uses many subtle and powerful JavaScript idioms in under 100 lines of code (including comments). And even though John’s article explains his intentions and the trickier bits, an experienced JavaScript programmer can still find it difficult to follow.

Recently I re-familiarized myself with Class.js, so this article is my recounting of how I understand how Class.js works.

This article is long, so I’ve broken into sections:

  1. What is Class.js for?

    Describes the problem Class.js attempts to solve.

  2. Overview of Class.js

    Describing the Class.js API and how it works.

  3. Line by line

    A review of some of the JavaScript techniques used.

What is Class.js for?

Above I describe Class.js as used for “simulating classical inheritance” in JavaScript. So what is that and why would you want that?

JavaScript, PHP, Java, Ruby, and many, many other programming languages allow programmers to define arbitrary “objects” to contain data and act upon that data. An object might represent something tangible, like a user or an invoice, or it may be more abstract, like a color. Objects allow a programmer to think of the problem they’re trying to solve in big conceptual chunks and break up their work into smaller units which can be easily understood and manipulated. Objects are sets of related information or data, and methods to act on or manipulate that data.

A classical language, like Java, defines these objects differently than a prototypical language, like JavaScript.

In classical programming languages, a class is a definition, or blueprint, for an object. When you hear ‘class’ think ‘classification’. You might classify a user in your program as having certain attributes like a user name, an email, or a password. Since all users are more or less the same, differing only in their particulars (my name is not your name, but we both have names), classes provide a way to define what all users are like in one place. When you create a new user, you create an instance of the user class; you create a new object which has the user class as its definition.

In JavaScript there are no classes, only objects. Everything in JavaScript is an object. Strings of text are objects, numbers are objects, functions are objects, dates are objects. Everything is an object. If you want a new object with specific properties, you can just create a new object with those properties.

var user = {
    “name”: “Bob Roberts”,
    “email”: “bob@example.com”,
    “password”: “dobolina”
};

If you want to make another user object, you can just create another object.

var otherUser = {
    “name”: “Malcolm Reynolds”,
    “email”: “captain@example.com”,
    “password”: “unificationday”
}

If you only need one or two of these user objects, this is easy. But what if you want to make hundreds? JavaScript allows any function to be used as a constructor for new objects. That means you can “define” an object within the body of a function.

function User(name, email, password) {
    this.name = name;
    this.email = email;
    this.password = password;
}

var user = new User(“Malcolm Reynolds”, “captain@example.com”,”unificationday”);
var otherUser = new User(“Bob Roberts”, “bob@example.com”, “dobolina”);

The new keyword tells JavaScript that you want to use the function as a constructor – to construct new objects. Without the new keyword the function would just set variables in the containing scope (probably the browser window)…so you wouldn’t get a new object.

Constructors streamline the creation of new objects which share properties and also allow you to compare constructed objects with the instanceof operator. We can know if “user” and “otherUser” were created by the same constructor

user instanceof User && otherUser instanceof User == true; 

Classical languages have constructors too. Constructors are called automatically when an instance of a class is created. Classical constructors only exist as a part of a class definition, whereas in JavaScript any old function can be a constructor if you want it to.

JavaScript allows for arbitrary definition of objects without classes. Constructor functions for times when more regularly defined or typed objects are required. Classical languages require classes to define new objects.

From these examples it might look like JavaScript has a superior, more flexible, and expressive system for making new objects. But there’s more to objects than constructors and classes.

Inheritance

If all of the users in your program are the same, then you only need one class or one constructor function to deal with them all. Once you have different types of users (pilots, mechanics, doctors) then you need a way to specify their differences (training, tools), while reusing the things they share (name, email, password).

In a classical language we would create a new class of user which extends the User class (in pseudo-code):

public class User {
    public String name;
    public String email;
    public String password
}

public class Pilot extends User {
    public String license;
}

Our new Pilot class gets all of the User features for “free” while only having to define the parts that are different, the Pilot license. A call to new Pilot() gets a Pilot object with all the properties of a User object.

In JavaScript, there are no classes, only objects. So how do you create an object based upon another object? With another object.

A JavaScript object can have a prototype – an object which an object is based upon. Using our User constructor from above, we can make a new user:

var userPrototype = new User();

This user will not have a name, email, or a password.

We can then make a new constructor function for pilots:

function Pilot(name, license) {
    this.name = name;
    this.license = license;
};

And then we can define the Pilot’s prototype to be an object created by the User function, a user object:

Pilot.prototype = userPrototype

Now any new user we create with the Pilot constructor function will have all of the same properties as any user.

But.

What about the email and password properties? Oops. We didn’t include those in the Pilot constructor function. Maybe it should have been written like this?

function Pilot(name, email, password, license) {
    this.name = name;
    this.email = email;
    this.password = password;
    this.license = license;
}

Or maybe we should have written things this way?

function User = function() {};
User.prototype = {
    name: ‘’;
    email: ‘’;
    password: ‘’
};

var pilotProto = {license: ‘’};
var user = new User();
for(key in pilotProto) {
    user[key] = pilotProto[key];
}
function Pilot() {};
Pilot.prototype = user;

You can see how this can start to get cumbersome, especially compared to the tidy classical example. Every time you want to create an object based upon a user, you must create a user to use as a prototype. This is powerful – any object can extend any other object. You can add features to all instances created by any constructor by manipulating the constructor function’s prototype. Very powerful, but, it’s messy.

And so

Class.js hides all of this constructor function creating, object prototyping, and property copying behind a single function called extend. That’s the big win. It makes all of the above stuff simple by wrapping it into generic code and establishing a convention for constructors to follow when used for creating prototypes.

Learn more about JavaScript’s object model

The JavaScript object model is powerful and very flexible. The examples I have above are very basic and only serve to illustrate how object inheritance can be somewhat cumbersome when things get complicated.

The Mozilla Developer Network has a great article which goes into depth about JavaScript’s object model and compares it to a classical object model for reference. It’s a clearly written article and a great reference.

Overview of Class.js

When using Class.js you pass an object to the static extend method. Then extend returns a new constructor function whose prototype has the same properties and methods as the object you provided. The newly returned constructor has its own copy of the extend method so that you may extend this constructor as well. It looks like this:

var piratePrototype = {
    eyepatch: true,
    talk: function() {
        return “yar”;
    }
};
var Pirate = Class.extend(piratePrototype);

var blackbeard = new Pirate();
blackbeard.talk(); // returns “yar” 

var spacePiratePrototype = {
    blaster: true,
    blast: function() {
        return “zap”;
    }
};
var SpacePirate = Pirate.extend();

var han = new SpacePirate();
if (han.blaster) {
    han.blast(); // returns “zap”
    han.talk(); // returs “yar”
}

Let’s walk through how Class.js works

The “Class” class

Class.js first creates a generic, empty constructor function called Class and assigns it to the global scope. Class does nothing, it is merely establishes a base object to extend.

If you inspect a constructor function named MyConstructor created with Class.js in your browser’s console you will find the following to be true.

MyConstructor instanceof Class

Extending

After defining Class, the extend method is defined. extend does all of the important work of creating constructors which inherit the right prototype.

extend accepts a generic object as its only parameter. This generic object will contain the properties and methods (functions) shared by all objects created by the constructor which extend creates. The provided object can be thought of as a prototype for all objects created by the constructor.

extend is a method attached to the constructor Class. Any constructors created by the extend method will also have an extend method. This allows each constructor to extend itself. So if you create a new constructor like this:

var MyConstructor = Class.extend({“name”: “Pavel”, “rank”: “Admiral”});

Then the new constructor function MyConstructor will have its own extend method.

var MyExtendedConstructor = MyConstructor.extend({“wessels”: “nuclear”});

When extend is called on MyConstructor, a new instance of MyConstructor is created. The prototype object is merged with the new instance to create a new, complete prototype object. When MyExtendedConstructor is used to create new objects (as a constructor) the properties of both MyConstructor and MyExtendedConstructor will be included. You will be able to compare objects created by either constructor:

var admiral  = new MyExtendedConstructor();
admiral instanceof MyExtendedConstructor == true;
admiral instanceof MyConstructor == true;
admiral instanceof Class == true;

It’s important to note that only the constructor functions created by extend have an extend method. Instances do not. The following will not work:

var m = new MyConstructor();
m.extend({“photos”: “high energy”}); // fails, extend is undefined

Super

In classical programming languages classes which extend other classes automatically inherit properties and functions of the parent class.

Here’s a parent class in pseudo-code:

public class Car {
    public bool driving = false;
    public void drive() {
        this.driving = true;
    }
}

Now if we extend that class:

public class Truck {
    public bool hauling = false;
    public void haul() {
        this.hauling = true;
        this.drive();
    }
}

Notice I get the drive method for free. I don’t have to redefine it. This automatic code reuse is one of the important time saving features of object oriented programming.

But what if I wanted the Truck class’ drive method to work differently? I could just redefine it in my extended class?

public class Truck {
    public bool hauling = false;
    public void drive() {
        this.driving = true;
        this.hauling = true; // whoops. I’ve just recreated the original drive method
    }
}

This will work just fine, but now I’ve just recreated the functionality of the original drive method. I’m not saving myself any effort. To reuse the original drive method in my new drive method, I call the drive method on the parent class:

public class Truck {
    public bool hauling = false;
    public void drive() {
        this.parent.drive();
        this.hauling = true;
    }
}

In JavaScript the same thing can be accomplished with use of a constructor’s prototype.

function Car() {
    this.driving = false;
}
Car.prototype.drive = function() {this.driving = true;}

function Truck() {
    this.hauling = false;
}
Truck.prototype = new Car();
Truck.prototype.constructor = Truck;
Truck.prototype.drive = function() {
    Car.prototype.drive.call(this);
}

var t = new Truck();
t.drive();
t.driving == true; // set by Car.prototype.drive
t.hauling == true; // set by Truck.prototype.drive

With this arrangement the drive function of the Truck prototype reuses the drive function of the Car prototype. This works, and successfully reuses code, but it’s a little bit brittle. For example, if I decide to change the name of my Car constructor function to Vehicle and I fail to update my Truck constructor, Truck will no longer work. Class.js works around this brittleness by creating a generic function named _super for each extended method.

var carPrototype = {
    driving: false,
    drive: function() {
        this.driving: true;
    }
};
Car = Class.extend(carPrototype);

var truckPrototype = {
    hauling: false.
    drive: function() {
        this._super(); // calls the drive method from Car
        this.hauling = true; 
    }
};
Truck = Car.extend(truckPrototype);

Here, the more generic _super replaces Car.prototype.drive, which is much tidier. It also has another benefit

var breadTruckPrototype = {
    cargo: ‘’,
    drive: function() {
        this._super(); // calls Truck.drive which calls Car.drive. 2 for 1!
        this.cargo = “bread”;
    }
};
BreadTruck = Truck.extend(breadTruckPrototype);

The _super method here calls Truck.drive, which calls Car.drive without having to reference multiple specific prototypes by name.

Init

Class.extend generates constructor functions with prototypes you define, but often times you want a constructor function to do some actual work in addition to just creating a new object instance.

If you create a method named init in the prototype object passed to Class.extend, the constructor function that gets created will call your init method automatically…but only when you’re making new instances, not when you’re extending. It works like this:

var helmsmanPrototype = {
    init: function(name, weapon) {
        this.name = name;
        this.weapon = weapon || “phaser”;
    },
    name: undefined,
    weapon: undefined
}

var Helmsman = Class.extend(helmsmanPrototype);

var sulu = new Helmsman(“Sulu”, “sword”);
var chekov = new Helmsman(“Chekov”);

In the above example, Class.extend creates a constructor function which automatically calls init when a new instance is created. The parameters are passed along automatically as well.

In the init method above I use the following JavaScript shorthand:

this.weapon = weapon || “phaser”;

This is a means of setting default values. You could read the line as “If weapon has a value, set this.weapon to that value, otherwise use ‘phaser’”. In the example, chekov uses the default weapon, a phaser, while sulu gets a sword. Because sulu is awesome.

Line by line

For easy reference, I’ve placed a syntax-highlighted copy of Class.js here.

Class.js uses a few clever JavaScript tricks as well as some unusual conventions to accomplish its goals. When I was first learning I found some bits to be completely inscrutable. Once I understood them I reach a new level of JavaScript enlightenment.

Anonymous function wrapper

The first line of code, line 6, beneath the opening comments, and the last line together form an auto-executing anonymous function. See below with the rest of the code removed:

(function(){
 // … the rest of Class.js here
 })();

Within the first two parentheses a function is defined, which contains all of Class.js. At the end that function is executed. This little trick encloses a bit of functionality in its own scope. No JavaScript executed outside of this anonymous function can effect what’s going on inside that function (JavaScript has function-level scope, instead of block level scope). We’ll see a little later how you can export items within the anonymous function to the containing scope. This pattern is used by jQuery plugin authors, it’s auto-generated by stupid CoffeeScript, and in general is a good idea for small, self-contained libraries.

Setting variables

On line 7 generic variables for use throughout Class.js are set. It’s considered good practice to declare your variables at the beginning of a JavaScript functions for reasons that relate to how JavaScript is parsed and executed. For those who have to read your code later (including yourself) it’s good practice. The first variable, initializing is used by the extend method, defined later. What’s clever here is the second variable fnTest.

fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/;

fnTest is assigned the result of a ternary expression. A ternary is a short-hand way of writing the following:

if (condition == true) {
    output = ‘condition is true output’;
} else {
    output = ‘condition is false output’;
}

// in ternary form
output = (condition) ? ‘condition is true output’ : ‘condition is false output’;

This structure allows you to quickly test for a condition, and assign one of two results to a variable based upon that condition. It happens enough in programming that special constructions were created to make it quick to write.

For fnTest the condition being tested is this:

/xyz/.test(function(){xyz;})

This is a dense one-line of code. /xyz/ is a Regular Expression defined with JavaScript literal syntax. Regular Expression objects have a test method, so this is calling the test method of the literal Regular Expression /xyz/. The test checks to see if the text you provide matches the regular expression, if it matches, it returns true. You can read /xyz/.test() as “tell me if the letters ‘xyz’, in that order, exist in the text I provide you”.

The test method expects a string, so if you pass it a number or an object, JavaScript will automatically convert it to a string. Here we’re passing an anonymous function to the test method:

function(){xyz;}

In JavaScript, functions are objects, and all objects have a toString method. In most reasonably modern browsers, when you call toString on a function object, JavaScript will return the literal text you used to write the function. You can actually look inside the function to see how it was written. So the entire conditional expression is testing for that browser feature. Let’s look at the expression again:

fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/;

So, the conditional is testing that result of the toString method of a function returns the body of the function. The Regular Expression is looking for “xyz”, the function body contains “xyz”, if the conditional returns true, then we know we can inspect then inside of a function.

If that’s true, a new regular expression is returned:

/\b_super\b/

As discussed in the previous section, Class.extend creates a _super property when extending classes. This new Regular Expression will be used to test if _super is being used within the body of a function.

If the xyz-function test fails, a generic regular expression is returned which matches everything (test will return true for any string). This is a fall-back for older browsers. If the browser provides a feature, we can take advantage of it, if not, we can use a default case which works for every browser.

Exporting to global scope

On line 10 the Class constructor function is created.

 this.Class = function(){};

As described above, this function doesn’t do anything, it only serves as a container for the extend method. The interesting bit here is the this keyword prepended to Class. The keyword this refers to the containing scope of the current function. In this case the containing scope is the global or window scope (assuming this is executed in the browser). Assigning Class to this is a more generic means of writing window.Class – it’s generic in that it doesn’t assume what the global scope is. This can be thought of as “exporting” Class to the global scope. It’s tidier than defining a global variable outside of the anonymous function wrapper.

Create prototype

The extend method is defined on line 13. Below, on line 18 we see the variable initializing in use while creating the base prototype object. initializing is set to true while the base constructor is called, then set back to false.

initializing = true;
var prototype = new this();
initializing = false;

We’ll see how this works in the constructor function definition below.

To create the prototype, new this(); is called. This (or this) works because this refers to the constructor function Class defined above, extend is defined as a property of the Class function object. If JavaScript were a classical language, you would refer to extend as a “static method”.

When you create a new constructor function with extend the keyword this will now refer to that new constructor function. This way this always refers to the constructor you’re extending.

Super

Beginning on line 23 the properties passed into the extend function (the parameter prop) are copied onto the newly created prototype object created by new this() above. The for … in loop iterates over the properties of the prop object. On line 25 values from prop are copied into the new prototype object. But what comes next is a bit hairy.

This assignment uses another ternary expression, like fnTestabove. The assignment and conditional portion in the ternary expression is this:

prototype[name] = typeof prop[name] == "function" && typeof _super[name] == "function" && fnTest.test(prop[name])

There are a number of players here, so let’s identify each:

prototype
the new based prototype created by calling new this() above.
prop
the object passed to extend containing the properties and methods to be added to prototype
_super
the current, existing prototype of the parent function, the owner of the extend method which received prop as a parameter.
name
the string name of the current property being copied

The conditional statement checks if both prop and _super have a property with the same name, and that both properties are functions. If so and that function passes fnTest (the function contains the text _super), then a special copy of _super[name] is made and made available to prop[name].

If the properties being compared aren’t functions, or don’t pass the fnTest then no special _super function is defined – if _super is not used, then there’s no reason to do the work.

Wrap up

Line 47 defines the constructor function that extend will return. The constructor has one job, to check initializing and if it’s false, check for a function called init and call it with any arguments passed to the constructor.

function Class() {
  // All construction is actually done in the init method
  if ( !initializing && this.init )
    this.init.apply(this, arguments);
}

It’s a little confusing that this function is also named “Class” – the whole thing is named “Class” so how does that work? Here Class is defined within the cope of the extend method, so it doesn’t conflict with the Class function that was explicitly defined in the global scope with this.Class.

Next the updated prototype, with all the properties and methods from prop added in, is set as the prototype of Class:

Class.prototype = prototype;

The constructor function of the prototype is explicitly set:

Class.prototype.constructor = Class;

The extend method is copied (referenced) to the new constructor so it can be extended itself.

Class.extend = arguments.callee;

The special variable arguments is an array of all the parameters passed to a function. JavaScript creates it automatically whenever a function is called. It has a special property callee which means “the function that received these arguments. Here it refers to extend allowing extend to be applied to the scope the new constructor function.

Finally the new constructor is returned, ready for business:

return Class;