This blog post looks at the special property __proto__, which allows you to get and set the prototype of an object. In order to understand this post, you should be familiar with JavaScript’s prototypal inheritance [1].
> var myProto = {}; > var obj = Object.create(myProto); > Object.getPrototypeOf(obj) === myProto true
__proto__ (pronounced “dunder proto”, from “double underscore” [2]) first appeared in Firefox and is an alias for [[Prototype]]. Using __proto__, the above code becomes:
> var myProto = {}; > var obj = { __proto__: myProto }; > obj.__proto__ === myProto trueThe following also holds:
> obj.__proto__ === Object.getPrototypeOf(obj) trueOnce it appeared in Firefox, __proto__ proved so popular that it is now also supported by V8 (Chrome, Node.js) and Nitro (Safari). As of ECMAScript 5, it is still non-standard, but due to its popularity, it will become part of ECMAScript 6.
Object.getPrototypeOf({ __proto__: null }) === null
function escapeKey(key) { // We need to escape "__proto__", including the // (n times) escaped version of it, to avoid clashes if (key.indexOf("__proto__") === 0) { return key+"%"; } else { return key; } }Obviously, you have to escape keys for both read and write access. Thus, you never need to un-escape.
var obj = { __proto__: myProto, foo: 123, bar: "abc" };With Object.create(), you have two, equally unappealing, alternatives:
// Alternative 1: create empty object, assign var obj = Object.create(myProto); obj.foo = 123; obj.bar = "abc"; // Alternative 2: property descriptors var obj = Object.create(myProto, { foo: { value: 123, writable: true, enumerable: true, configurable: true }, bar: { value: "abc", writable: true, enumerable: true, configurable: true } });
var MyArrayProto = Object.create(Array.prototype); MyArrayProto.foo = function (...) { ... }; function createMyArray() { var arr = Array.prototype.slice.call(arguments); arr.__proto__ = MyArrayProto; } var myarr = createMyArray();
It is not yet certain that you’ll also be able to change the prototype of an existing object via __proto__. The most important use case for that is to subtype Array, which can be better supported by other means, e.g. via a function Array.createArray(proto).
Lastly, ECMAScript 6 will probably also provide ways for switching off __proto__ for some objects, possibly even for all objects.