Uninheritance Using Undefined in Javascript

Javascript has a value called undefined. It’s an interesting little fella, which is the value of everything that is not defined. One common use of it is trolling your javascript console:


> defined
ReferenceError: defined is not defined
> var o = {}
undefined
> o.defined == undefined
true

Ha ha, silly javascript, not can’t even tell defined from it’s opposite. Except that it can. And it’s also very elegant.

See, unlike other dynamic languages that requires programs to test the symbol table for symbol presence (e.g. ruby’s defined?() method), javascript does not have to test the table, since every valid expression (such as a variable reference) has a value. It just may be that this is undefined.

Common inheritance models allows programmers to refine behavior (when overriding methods) or to extend them (when adding new methods). But javascript, with it’s undefined and its prototype-based inheritance, has a new type of inheritance – inheritance with method deletion.

Suppose we want to model vehicles. Vehicles can go, er, I mean go(), and they also have a number of doors. Easy enough, here’s the vehicle object, and a car and a truck.


var vehicle = Object.create({});
vehicle.go = function() { return this.name + " is going"; };
vehicle.doors = function() { return this.doorCount; };
// make a truck
var truck = Object.create( vehicle );
truck.doorCount = 2;
truck.name="Truck";
// make a car
var car = Object.create( vehicle );
car.doorCount = 5;
car.name="Car";

This works fine (all examples here were executed using Firefox Developer Edition):

> var aCar = Object.create(car);
undefined
> aCar.name="MyLittlePony";
"MyLittlePony"
> aCar.go()
"MyLittlePony is going"

Nothing new so far. But how do you go about modeling a broken car? When using languages that use class-based inheritance, such as Java, one might result to throwing an IllegalStateException, since brokenCar is a vehicle and thus must have a go() method. In javascript, however, there’s another option:


> var brokenCar = Object.create( car )
undefined
> brokenCar.go = undefined;

And now:

> brokenCar.doors()
5

But

> brokenCar.go()
TypeError: brokenCar.go is not a function

In other words, brokenCar is a car that can’t go, just like in real life, where a broken car is a car that can’t go.

Achievement “modeling bliss” unlocked.