ProtoType

Introduction

  • Every object in JavaScript has a built-in property, which is called its prototype. The prototype is itself an object, so the prototype will have its own prototype, making what's called a prototype chain. The chain ends when we reach a prototype that has null for its own prototype.

  • When you try to access a property of an object: if the property can't be found in the object itself, the prototype is searched for the property. If the property still can't be found, then the prototype's prototype is searched, and so on until either the property is found, or the end of the chain is reached, in which case undefined is returned.

Example

const myDate = new Date();
let object = myDate;

do {
  object = Object.getPrototypeOf(object);
  console.log(object);
} while (object);

// Date.prototype
// Object { }
// null

Setting ProtoType of Object

Method 1 (Object Assign)

// case 1
function Person(name, age) {
  this.name = name;
  this.age = age;
  this.log = function () {
    console.log(this.name + ', age:' + this.age);
  }
}

var nick = new Person('nick', 18);
var peter = new Person('peter', 20);

console.log(nick.log === peter.log) // false

// case 2
function Person(name, age) {
  this.name = name;
  this.age = age;
}

const PersonPrototype = {
  log(){
      console.log(this.name + ', age:' + this.age);
  }
}

Object.assign(Person.protoType, PersonPrototype);
// or Person.prototype.log = personPrototype.log;

var nick = new Person('nick', 18);
var peter = new Person('peter', 20);

console.log(nick.log === peter.log) // true
// since the method is shared without creating new reference same as case 1

Method 2 (By property)

// case 1
const parent = {
  value: 2,
  method() {
    return this.value + 1;
  },
};

console.log(parent.method()); // 3
// When calling parent.method in this case, 'this' refers to parent

// child is an object that inherits from parent
const child = {
  __proto__: parent,
};
console.log(child.method()); // 3
// When child.method is called, 'this' refers to child.
// So when child inherits the method of parent,
// The property 'value' is sought on child. However, since child
// doesn't have an own property called 'value', the property is
// found on the [[Prototype]], which is parent.value.

child.value = 4; // assign the value 4 to the property 'value' on child.
// This shadows the 'value' property on parent.
// The child object now looks like:
// { value: 4, __proto__: { value: 2, method: [Function] } }
console.log(child.method()); // 5
// Since child now has the 'value' property, 'this.value' means
// child.value instead


// case 2
const obj = {};
// DON'T USE THIS: for example only.
obj.__proto__ = { barProp: "bar val" };
obj.__proto__.__proto__ = { fooProp: "foo val" };
console.log(obj.fooProp);
console.log(obj.barProp);

Method 3 (By setPrototypeOf)

const obj = { a: 1 };
const anotherObj = { b: 2 };
Object.setPrototypeOf(obj, anotherObj);
console.log(obj.b) // 2
// obj ---> anotherObj ---> Object.prototype ---> null

Method 4 (By Class)

// case 1
function Base() {}
function Derived() {}
// Set the `[[Prototype]]` of `Derived.prototype`
// to `Base.prototype`
Object.setPrototypeOf(Derived.prototype, Base.prototype);

const obj = new Derived();

// equal
class Base {}
class Derived extends Base {}

const obj = new Derived();
// obj ---> Derived.prototype ---> Base.prototype ---> Object.prototype ---> null


// case 2
// A constructor function
function Box(value) {
  this.value = value;
}

// Properties all boxes created from the Box() constructor
// will have
Box.prototype.getValue = function () {
  return this.value;
};

// equal
class Box {
  constructor(value) {
    this.value = value;
  }

  // Methods are created on Box.prototype
  getValue() {
    return this.value;
  }
}

Decide own property

function Person(name, age) {
  this.name = name;
  this.age = age;
}

const PersonPrototype = {
  log(){
      console.log(this.name + ', age:' + this.age);
  }
}

// Person.prototype.log =  PersonPrototype.log;
Object.assign(Person.prototype, PersonPrototype);
var nick = new Person('nick', 18);
nick.log(); // nick, age:18
console.log(nick.hasOwnProperty('log')); // false
console.log(nick.__proto__.hasOwnProperty('log')); // true

Last updated

Was this helpful?