- Inheritance, the
__proto__ Object.create,Object.getPrototypeOf- The
prototype - Crossbrowser
Object.create(proto) hasOwnProperty- Looping with/without inherited properties
- Summary
In most languages, there are classes and objects. Classes inherit from other classes.
In JavaScript, the inheritance is prototype-based. That means that there are no classes. Instead, an object inherits from another object ![]()
Inheritance, the __proto__
When an object rabbit inherits from another object animal, in JavaScript that means that there is a special property rabbit.__proto__ = animal.

When a rabbit property is accessed, and the interpreter can’t find it in rabbit, it follows the __proto__ link and searches in animal.
The examples using __proto__ work only in Chrome/Firefox. That’s for sheer simplicity. Later we’ll go crossbrowser.
var animal = { eats: true }
var rabbit = { jumps: true }
rabbit.__proto__ = animal // inherit
alert(rabbit.eats) // true
The eats property is actually taken from animal. Here’s the picture:

If the property is found in rabbit, then __proto__ is not checked.
For example, when eats is in the child object, parent is ignored:
var animal = { eats: true }
var fedUpRabbit = { eats: false}
fedUpRabbit.__proto__ = animal
alert(fedUpRabbit.eats) // false

One could put a method into animal and it becomes available in rabbit:
var animal = {
eat: function() {
alert( "I'm full" )
this.full = true
}
}
var rabbit = {
jump: function() { /* something */ }
}
rabbit.__proto__ = animal
*!*
rabbit.eat()
*/!*
The rabbit.eat() is executed in two steps:
- First, the interpreter looks up
rabbit.eat. There’s noeatinrabbitobject, so it goes torabbit.__proto__and finds it there.
- The function runs with
this = rabbit.The value of
thisis completely irrelevant to__proto__. It is set exactly to the object before the dot (see more aboutthishere).So,
this.full = truestores the value in therabbitobject:
Look what we’ve got. An object calls parent method, but this is set to the object itself. That’s the inheritance.
The object, referenced by __proto__ is called a prototype. So, animal is a prototype of rabbit.
When a property is read, like this.prop, the interpreter looks it in the prototype.
When a property is assigned, like this.prop = value, then there is no reason to search. The property is written directly into the object (here this).
Same with delete obj.prop. It only deletes the property on object itself, and leave it intact if it is in the prototype.
If you’ll be reading the specification, what we call __proto__ here is named [[Prototype]] there. And yes, double square brackets are important, because there’s another property named prototype.
Object.create, Object.getPrototypeOf
The __proto__ is a non-standard property, provided by Firefox/Chrome. In other browsers the property still exists internally, but it is hidden.
All modern browsers except Opera (IE from 9) support two standard methods for working with prototypes:
- Object.create(proto[, props])
- Creates an empty object with given
__proto__:var animal = { eats: true } rabbit = Object.create(animal) alert(rabbit.eats) // trueThe code above creates empty
rabbitwith animal__proto__:
Once the rabbit is created, we can add properties to it.
var animal = { eats: true } rabbit = Object.create(animal) rabbit.jumps = trueThere second argument
propsis optional and allows to set properties of the new object. Here we skip it, because we are concerned about the inheritance part.
- Object.getPrototypeOf(obj)
- Returns the value of
obj.__proto__. The method is standard, so it works in browsers which don’t support__proto__property:var animal = { eats: true } rabbit = Object.create(animal) alert( Object.getPrototypeOf(rabbit) === animal ) // trueSo, most modern browsers allow to read the value of
__proto__, but not to modify it.
The prototype
There is a good and crossbrowser way of setting __proto__. It requires the use of constructor functions.
Remember, any function creates an object when called with new. Here’s a simple Rabbit constructor to start with:
function Rabbit(name) {
this.name = name
}
var rabbit = new Rabbit('John')
alert(rabbit.name) // John
A new function call sets the __proto__ of the object to the value of its prototype property.
Let’s see how it works. For example, let’s make new Rabbit objects which inherits from animal:
var animal = { eats: true }
function Rabbit(name) {
this.name = name
}
Rabbit.prototype = animal
var rabbit = new Rabbit('John')
alert( rabbit.eats ) // true, because rabbit.__proto__ == animal
The code Rabbit.prototype = animal literally means the following:
”set __proto__ = animal for all objects created by new Rabbit”.
What is the result of the code? Why?
function Rabbit(name) {
this.name = name
}
var john = new Rabbit('John')
var animal = { eats: true }
Rabbit.prototype = animal
alert(john.eats)
The result is undefined, because the prototype property is set after the new Rabbit.
As a consequence, john doesn’t have animal prototype, and hence there’s no eats property.
Changing the prototype has no effect on already-created objects.
Crossbrowser Object.create(proto)
The functionality of Object.create(proto) is great, because it allows to inherit directly from the given object. It can be emulated by our own method which works in all browsers.
Here’s the function:
function inherit(proto) {
function F() {}
F.prototype = proto
return new F
}
The result of inherit(animal) is identical to Object.create(animal): an new empty object, with object.__proto__ = animal.
For example:
var animal = { eats: true }
var rabbit = inherit(animal)
alert(rabbit.eats) // true
alert(rabbit.hasOwnProperty('eats')) // false, from prototype
Let’s go into details how it works. There are just three lines:
function inherit(proto) {
function F() {} // (1)
F.prototype = proto // (2)
return new F() // (3)
}
- A new function
Fis created. The function doesn’t set anything tothis, sonew Fcreates an empty object. F.prototypeis set to givenproto- The result of
new Fis an empty object with__proto__set to the value ofF.prototype, which isproto. - Bingo! We’ve got an empty object with given
proto.
The function is widely used in libraries and frameworks.
Your function receives an object with options.
/* options contains menu settings: width, height etc */
function Menu(options) {
// ...
}
You want to “fix” certain options:
function Menu(options) {
options.width = options.width || 300 // set default value
// ...
}
… But changing the argument may have bad consequences, because options may be reused in external code.
One way to workaround is to clone options by copying all properties into a new object, and modify it there. This implies certain overhead.
How to solve this problem effectively using inheritance?
P.S. Options can be modified/added, but never removed.
You can inherit from options and modify/add options in the child object:
function inherit(proto) {
function F() {}
F.prototype = proto
return new F
}
function Menu(options) {
var opts = inherit(options)
opts.width = opts.width || 300
// ...
}
All changes will be reflected in the child object only. When Menu finishes, the external code can continue with unmodified options.
The P.S. about deletion is important here, because delete opts.width doesn’t do anything if width is in prototype.
hasOwnProperty
All objects have hasOwnProperty method which allows to check if a property belongs to the object or its prototype.
For example:
function Rabbit(name) {
this.name = name
}
Rabbit.prototype = { eats: true }
var rabbit = new Rabbit('John')
alert( rabbit.hasOwnProperty('eats') ) // false, in prototype
alert( rabbit.hasOwnProperty('name') ) // true, in object
Looping with/without inherited properties
A for..in loop outputs all properties from the object and its prototype:
function Rabbit(name) {
this.name = name
}
Rabbit.prototype = { eats: true }
var rabbit = new Rabbit('John')
for(var p in rabbit) {
alert (p + " = " + rabbit[p]) // outputs both "name" and "eats"
}
To get a list of properties, which are not in prototype, filter them through hasOwnProperty:
function Rabbit(name) {
this.name = name
}
Rabbit.prototype = { eats: true }
var rabbit = new Rabbit('John')
for(var p in rabbit) {
*!*
if (!rabbit.hasOwnProperty(p)) continue // filter out "eats"
*/!*
alert (p + " = " + rabbit[p]) // outputs only "name"
}
Summary
The inheritance is implemented through a special property __proto__ (named [[Prototype]] in the specification).
- When a property is accessed, and the interpreter can’t find it in the object, it follows the
__proto__link and searches it there. - The value of
thisfor function properties is set to the object, not its prototype. - Assignment
obj.prop = valand deletiondelete obj.prop
Managing __proto__:
- Firefox/Chrome give direct access to
obj.__proto__. Most recent browsers support read-only access withObject.getPrototypeOf(obj). - An empty object with given prototype can be created by
Object.create(proto)in most modern browsers, or the following function in all browsers:function inherit(proto) { function F() {} F.prototype = proto return new F } - A constructor function sets
__proto__for objects it creates to the value of itsprototypeproperty.
Additional methods:
for..inloop lists properties in the object and its prototype chain.obj.hasOwnProperty(prop)returnstrueonly if thepropbelongs toobj, not its prototype.