The term “prototype and inheritance” is often asked in interviews, but is often used in real development. In order to break the awkward situation of not knowing each other even if you meet them, this article will comb through the concepts of archetype and inheritance and show you how they can be used in practice.

The prototype

JS has no replication mechanism, so JS creates an association between two objects and then delegates to the other object.

For example, if we have an object child whose prototype is parent, then:

  • Child has a __ proto __ property that points to the parent object;
  • Child’s constructor, CreateChild, has a Prototype property that also points to parent.

Similarly, parent will have __ proto __, which points to its prototype, and so each level of the prototype chain will form up to the object’s prototype (NULL).

Using the prototype

One of the most important aspects of prototyping is data sharing. When creating objects, we attach common methods and properties to the prototype to avoid wasting resources.

Methods a

Assign the function prototype property to the object itself to set the prototype for foo

var foo = function() {
   this.a: 'hello';
}

foo.prototype = {
    add: (x, y) = > x + y;
}

var bar = new foo();
Copy the code

If you add attributes to Bar Prototype, foo will also add attributes

bar.prototype = {
    substract: (x, y) = > x-y
}
Copy the code

Way 2

Using IIFE to assign values, you can encapsulate private attributes and variables and expose method names in the form of return to achieve public/private effect

Calculator.prototype = function () {
    add = function (x, y) {
        return x + y;
    },

    subtract = function (x, y) {
        return x - y;
    }
    return {
        add: add,
        subtract: subtract
    }
} ();

var zsh = new Calculator()
zsh.add(11.3) / / 14
Copy the code

inheritance

The prototype inheritance model is the principle of JavaScript implementation inheritance. As we mentioned earlier, JS uses delegates to access other objects so that we don’t have to implement a separate method that inherits a property.

The way inheritance is implemented

// Implement one, prototype chain inheritance
// Defect: instances share one stereotype, and property changes affect others
function parent2() {
  this.name = 'parent2';
  this.play = [1.2.3];
}

function child2() {
  this.type = 'child2';
}

child2.prototype = new parent2(); // Bridge the prototype chain

var instance = new child2;
instance.play.push(4);
alert(instance.play); // [1, 2, 3, 4]

var instance2 = new child2;
alert(instance2.play); // [1, 2, 3, 4]

// Implement two, constructor inheritance
// Advantages: attributes are isolated from each other; You can pass parameters
// Defect: the methods of the parent class are not shared, the prototype method is copied by call, the subclass cannot access and inherit, resulting in memory waste
function parent1() {
  this.name = 'parent1';
  this.toString = '333';
}

function child1() {
  parent1.call(this); // The constructor of the superclass is called in the future for each subclass instance, and each subclass has its own copy of Play
  this.type = 'child1';
}

console.log('new child1 :>> '.new child1());

// Implement three, composite inheritance
// Using a combination of stereotype and constructor inheritance, subclasses have their own attributes and can share methods
function parent() {
	this.colors = ['red'.'blue']}function child() {
	parent.call(this)
}

child.prototype = new parent();
child.prototype.constructor = child;

var c1 = new child()
c1.colors.push('green'); // ["red", "blue", "green"]
var c2 = new child() // c2.colors are still ["red", "blue"]

// Implement four, parasitic combination inheritance
function parent3() {
  this.name = 'parent2';
  this.play = [1.2.3];
}

function child3() {
  parent3.call(this); // Access properties in parent by displaying bindings
  this.type = 'child3';
}

child3.prototype = Object.create(parent3.prototype); // No prototype chain Bridges are generated
// Because child3's prototype points to another prototype -- parent3 -- its constructor points to parent3
child3.prototype.constructor = child3; // So to fix the constructor for child3,
console.log('new child3() :>> '.new child3());

// Implement 5, ES6 class
class parent4 {
  constructor() {}
  name() {
    return 'lee'; }}class child4 extends parent4 {
  constructor() {
    super();
  }
}
const c4 = new child4();
console.log('c4 :>> ', c4.name());
Copy the code

The above introduces five ways to realize inheritance, which is the main content of this paper. The realization of inheritance will involve details such as prototype, new, and prototype coverage and sharing. There are also detailed comments in the code, be sure to try it yourself, experience more profound!