In JavaScript there's a pattern to achieve inheritance called "Functional inheritance" described in chapter 5 of Crockfords "JavaScript: the good parts".
One of the disadvantages of the pattern -- as compared to using the pseudo-classical pattern -- is that we lose the ability to distinguish types using the instanceof
operator.
Is there any way to achieve the same goal? How can we know that two objects are somehow related because they are of the same parent/base "type"?
Also how can we tell even though they are descendants of the same type they are different types themselves?
I don't know if not being able to use instanceof
is a big loss but it doesn't seem like it is.
Notes
For those who are not familiar with Crockford's explanation, you can see an example at: JSFiddle, taken from here.
The instanceof
operator is not special. You can implement it yourself as explained on the Mozilla Developer Network. See the accepted answer to the following question for more details:
JavaScript inheritance and the constructor property
Here's how the instanceof
operator can be implemented in JavaScript:
function instanceOf(object, constructor) {
while (object != null) {
if (object == constructor.prototype) { //object is instanceof constructor
return true;
} else if (typeof object == 'xml') { //workaround for XML objects
return constructor.prototype == XML.prototype;
}
object = object.__proto__; //traverse the prototype chain
}
return false; //object is not instanceof constructor
}
Want to implement instanceOf
for functional inheritance? That's easy to do too:
var object = child({ name: "a functional object" });
alert(object.instanceOf(child)); // true
alert(object.instanceOf(base)); // true
alert(object.sayHello()); // Hello, I'm a functional object
function base(spec) {
var that = {};
that.name = spec.name;
that.constructors = [base];
that.instanceOf = instanceOf;
return that;
}
function child(spec) {
var that = base(spec);
that.sayHello = sayHello;
that.constructors.push(child);
return that;
function sayHello() {
return "Hello, I'm " + this.name;
}
}
function instanceOf(constructor) {
return this.constructors.indexOf(constructor) >= 0;
}
Of course, in real functional programming there's no need to use instanceof
at all.