2013-01-03

JavaScript terminology: the two prototypes

In JavaScript, there is an unfortunate overloading of the term “prototype”.

Prototype 1: relationship between objects

On one hand, we have the prototype relationship between objects. Some properties in the ECMAScript laguage specification are internal. Internal properties are not directly accessible in JavaScript and their names are written in double square brackets. [[Prototype]], one such property, is used to establish the prototype relationship. An object points to its prototype via [[Prototype]] and inherits all of its properties. In ECMAScript 5, one can read the prototype of an object via Object.getPrototypeOf().
    > Object.getPrototypeOf({}) === Object.prototype
    true
And one can create a new object with a given prototype via Object.create():
    > var proto = { foo: 123 };
    > var obj = Object.create(proto);
    > obj.foo
    123
[1] has more on these two functions. ECMAScript 6 will allow you to access an object’s prototype via the special property __proto__ [2].

Prototype 2: property of constructors

On the other hand, each constructor has the property prototype which points to an object that becomes the prototype of all instances created by that constructor.
    > function Foo() {}
    > var f = new Foo();
    > Object.getPrototypeOf(f) === Foo.prototype
    true

Resolving the name clash

Usually the context makes it clear which of the two prototypes is meant. Should disambiguation be necessary then we are stuck with “prototype” for the relationship between objects, because that name has made it into the standard library, via getPrototypeOf. We thus need to find a different name for the object referenced by the prototype property. One possibility is “constructor prototype”, but that is problematic, because constructors have prototypes, too:
    > function Foo() {}
    > Object.getPrototypeOf(Foo) === Function.prototype
    true
Thus, “instance prototype” seems the best option.

References

  1. JavaScript inheritance by example
  2. JavaScript: __proto__

No comments: