Prototypal Inheritance Definition
Let's take the usual class example: a 2D Point. A Point has two coordinates x, y and a method print.
Using the definition of the prototypal inheritance written before, we will make an object Point with three properties: x, y and print. In order to create a new point, we just make a new object with __proto__ set toPoint.
This is completely different from the code given above. Point is now a function, we use a prototype property, the new operator. What the hell!?
How new works
- C++ has the notion of constructor, that initializes the instance attributes. Therefore, the new operator must target a function.
- We need to put the methods of the object somewhere. Since we are working on a prototypal language, let's put it in the prototype property of the function.
The new operator takes a function F and arguments: new F(arguments...). It does three easy steps:
- Create the instance of the class. It is an empty object with its __proto__ property set toF.prototype.
- Initialize the instance. The function F is called with the arguments passed and this set to be the instance.
- Return the instance
And just a small test to see that it works.
This looks really strange but what it does is really simple. It just creates a new object with its prototype set to whatever you want. It could be written as this if we allow the use of __proto__:
The following code is our Point example with the use of real prototypal inheritance.
However, the use of real prototypal inheritance (Object.create and __proto__) has some downsides:
- Not standard: __proto__ is non-standard and even deprecated. Also native Object.create and Douglas Crockford implementation are not exactly equivalent.
- Not optimized: Object.create (native or custom) has not yet been as heavily optimized as the newconstruction. It can be up to 10 times slower.
Some further reading:
- Douglas Crockford: Prototypal Inheritance
- MDC Documentation: __proto__
- John Resig: getPrototypeOf
- Dmitry Shoshnikov: OOP: ECMAScript Implementation