JavaScript prototypes by example
Tags: javascript, prototype, webdev, beginners
Published: 2019-11-04 15:59:10

---
title: JavaScript prototypes by example
published: true
description: Prototypes is a powerful feature in JS. Let's see how they work step by step.
tags: javascript, prototype, webdev, beginners
---

Prototypes in JavaScript are the mechanism to share common functionality between objects. They are powerful, but sometimes confusing. Let's explore prototype behavior by example. You can try and experiment with examples below in a browser's developer tools.

We start with constructor function `Object` to create object instances
```js
typeof Object; // function
```

It has `prototype` property with useful methods like `toString`, `valueOf`, e.t.c.
```js
Object.prototype; // {constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …}
```

Two ways of object creation
```js
var obj1 = new Object();
var obj2 = {};
```

Every object instance on creation receives `__proto__` property
```js
var obj = {};
obj.__proto__; // {constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …}
```

`Object.getPrototypeOf` is a modern replacement to the old `__proto__` property
```js
var obj = {};
Object.getPrototypeOf(obj) === obj.__proto__; // true
```

An object's `__proto__` and `Object.prototype` is exactly the same object
```js
var obj = {};
obj.__proto__ === Object.prototype; // true
```

Objects are different, but share the same prototype
```js
var obj1 = {};
var obj2 = {};
obj1 === obj2; // false
obj1.__proto__ === obj2.__proto__; // true
```

Prototype chain terminates with `null`
```js
var obj = {}
obj.__proto__.__proto__ // null
```

A property added to prototype is available to all instances (it's not recommended to modify built-in prototypes!)
```js
var obj1 = {};
var obj2 = {};
obj2.foo // undefined
obj1.__proto__.foo = 'bar';
obj2.foo; // bar
```

It's possible to create an object without a prototype. In this case handy methods like `toString`, `valueOf`, e.t.c. would not be available
```js
var obj1 = {a: 1};
var obj2 = Object.create(null);
obj2.__proto__; // undefined
obj1 + ''; // "[object Object]"
obj2 + ''; // Uncaught TypeError: Cannot convert object to primitive value
```

It's possible to change an object's `__proto__` link at any time
```js
var obj = {};
obj.toString(); // "[object Object]"
Object.setPrototypeOf(obj, null);
obj.toString(); // Uncaught TypeError: obj.toString is not a function
Object.setPrototypeOf(obj, Object.prototype);
obj.toString(); // "[object Object]"
```

You can construct prototype chains of any length
```js
var obj1 = {};
var obj2 = Object.create(obj1);
obj2.__proto__ === obj1; // true
```

If a property isn't found in an object, it's searched in prototype chain all way to the top
```js
var obj1 = {a: 1};
var obj2 = Object.create(obj1);
obj2.hasOwnProperty('a'); // false
obj2.a // 1
```

Properties creation happens in a current object, not in a prototype
```js
var obj1 = {a: 1};
var obj2 = Object.create(obj1);
obj2.hasOwnProperty('a'); // false
obj2.a; // 1
obj2.a = 2;
obj2.hasOwnProperty('a'); // true
obj2.a; // 2
obj2.__proto__.a; // 1
```

A property value is searched in a current object first. If it's not found, the search continues in the prototype chain until the property is found or prototype chain ends. This may cause performance issues as described in the post below {% link karataev/with-great-prototype-power-comes-great-responsibility-457m %}

Primitives has their own prototypes
```js
var n = 1;
n.__proto__ === Number.prototype; // true
n.__proto__.__proto__ === Object.prototype; // true
```

You can't change prototype of Object.prototype
```js
Object.setPrototypeOf(Object.prototype, {}); // Uncaught TypeError: Immutable prototype object '#<Object>' cannot have their prototype set
```

Cyclic proto chains are prohibited
```js
var obj1 = {};
var obj2 = {};
Object.setPrototypeOf(obj1, obj2);
Object.setPrototypeOf(obj2, obj1); // Uncaught TypeError: Cyclic __proto__ value
```

It was common to create function constructors and extends their prototypes with useful methods available to all instances
```js
var Cat = function() {};
Cat.prototype.sayHi = function() {return 'meow'};
var cat = new Cat();
cat.__proto__ === Cat.prototype; // true
cat.sayHi(); // "meow"
```

ES2015 class is a syntactic sugar on prototypes
```js
class Animal {};
var cat = new Animal();
cat.__proto__ === Animal.prototype; // true
```

Extending a class means extending a prototype chain
```js
class Animal {};
class Cat extends Animal {};
var cat = new Cat();
cat.__proto__.__proto__ === Animal.prototype; // true
```

Please share your examples of working with prototypes in the comments section.

### Further reading

[MDN](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Object_prototypes)

[You Don't Know JS](https://github.com/getify/You-Dont-Know-JS/blob/1st-ed/this%20%26%20object%20prototypes/ch5.md)

[The Modern JS Tutorial](https://javascript.info/prototypes)