Object-oriented JavaScript
inheritance and polymorphism
JavaScript’s built-in inheritance mechanism is unfortunately unclear (try to read the ECMA description of how it works). In the literature one sees lots of constructs meant to illustrate polymorphism, that either fail in some way to be polymorphic, or are too clumsy to use safely.
In JavaScript, functions are also of type Object (although the
typeof
operator applied to a function returns
“function”), and can therefore carry members, including properties that
reference other functions.
All JavaScript functions have a property
prototype
,
which is a reference to an Object.
The purpose of this property is to implement inheritance. It works as follows.
The technique is to set the prototype
of a
constructor to an object instance, which serves as the parent.
An object can then be created using operator
new
with the first constructor. For each
public member of the parent, operator
new
gives the created object a property that
refers to the parent’s member. An object created this way is called a
child of the parent object, and the child is said to
inherit the public members of the parent.
Any constructor may serve as a parent. For example:
There is nothing special about the parent constructor.
inheritance by prototype
There are two non-obvious constructs required to achieve inheritance: setting up the inheritance relation, and initializing the members of the parent class inherited by the child class. There is more than one way to do it, but this is the best I’ve found.
The setting of the prototype
class variable to an instance
of another class is the JavaScript analog of declaring that the one class
is derived from the other. (The constructor of the other class is obtained
automatically from the constructor
member of this Object.)
Note that the private members of the parent are not directly accessible to the child. That is as it should be.
Thanks to Pablo Krause for pointing out a bug in a previous version that had led me down a complicated road.
polymorphism
Polymorphism in JavaScript is now very easy. One simply makes different constructors for different kinds of child objects inheriting from the same parent.
JavaScript polymorphism has a feature one does not find in all object-oriented languages. One can add and override members even on the fly, after an object has been created. An object can acquire or lose properties and behaviors over time. (This feature is typical of scripting languages, but in Java and C++ it is either absent or achieved only with difficulty.)
People argue about whether this is real object-oriented programming, but I personally like it, because often one wants to model things in the real world that also acquire and lose properties and behaviors over time.
member overrides
In JavaScript, one doesn’t so much override a parent’s member, as replace it. This is very easy, but there is a catch.
In contrast to the situation in class-based languages, one must take steps to save the parent’s method before the child’s constructor replaces it, if the method of the parent is ever to be called by a child.
See
JavaScript Guide: Details of the object model
stack overflow: How to “properly” create a custom object in JavaScript?