JS language comprehension 04 inherited summary

Inherited knowledge is still a little messy, to sum up.

Essentially, JS inheritance which are critical (except instance attribute), the prototype of the prototype inheritance chain strand is achieved by the object __proto__attribute, which should point to another objectprototype

Inherited constructor

ES5 inside the most common inherited methods are the following two:

  1. Subclass performed inside the parent class ( call/ applychange this), examples of attribute inheritance
  2. Subclass prototypean instance of the parent class equals ( new 父类), examples of inherited attributes and attribute Prototype

ES6 inside use classand extendsimplementation inheritance

Specifically, the following (mentioned below 属性, unless otherwise specified, refers to all properties and methods)

Examples of inherited property

Within a subclass of the parent class to make calls callor applymethods, this can only inherit the property of the parent instance of the class, you can not inherit property on the prototype.

function Child() {
  Father.call(this)
}

Inherited prototype property

(1) directly equal prototype prototype subclass the parent class:

Child.prototype = Father.prototype;
Child.prototype.constructor = Child;

(2) using the Object.setPrototypeOfmethod of

Using the Object.setPrototypeOfmethod specified to make Child.prototype.__proto__equal Father.prototype, to achieve a prototype inherited property (the equivalent newpart of the process)

Object.setPrototypeOf(Child.prototype, Father.prototype);

(3) with an intermediate function

The third method is an improvement to a variety of the first method, the prototype subclasses to avoid changes affect the prototype parent class, by using an intermediate function:

const Temp = function(){};
Temp.prototype = Father.prototype;
Child.prototype = new Temp()
Child.prototype.constructor = Child;

(4) is traversed by a copy of the parent class prototype object, thereby achieving inheritance:

for (const i in Parent.prototype) {
  Child.prototype[i] = Parent.prototype[i]
}

Examples of attributes and inherits the prototype property

(1) Let the child object's prototype becomes the instance parent object:

Child.prototype = new Father();
Child.prototype.constructor = Child;

(2) the method by ES6 classand extendsinheritance achieved:

class Father {
}

class Child extends Father {
  constructor() {
    super();
  }
}

Note that, classit can only be defined on the prototype chain approach, so it can only inherit prototyping, prototype and can not inherit property.

Non-inherited constructor

Let an object to inherit an unrelated objects, since the two objects are ordinary objects, not a constructor, you can not use the constructor method inheritance.

By Object.createrealization

Object.createInherited between the prototype method is directly, rather than analog class, to achieve normal object (non constructor)

const child = Object.create(father, [childDescriptors])

It is actually implementedchild.__proto__ === father

By Object.setPrototypeOfrealization

Object.setPrototypeOfAnd Object.createall changes to the prototype chain (setting __proto__means property), and Object.getPrototypeOf(a)is used to get the object __proto__properties

Object.setPrototypeOf(child, father)

This method is implementedchild.__proto__ === father

By objectfunction

You can write your own function to achieve the above Object.setPrototypeOf()and Object.create()the (partially) function

function object(parent) {    
  function Child() {}    
  Child.prototype = parent;    
  return new Child();  
}

In fact, this approach can be seen as Object.create()a simple polyfill.

Achieved by copying

Parent objects can traverse, to achieve copy

Shallow copy:

function extendCopy(p) {    
  var c = {};    
  for (var i in p) {      
    c[i] = p[i];    
  }    
  c.uber = p;    
  return c;  
}

Deep copy:

function deepCopy(p, c) {
  var c = c || {};
  for (var i in p) {
    const type = Object.prototype.toString.call(p[i]).match(/\s(.+)\]/)[1].toLowerCase();
    switch (type) {
      case 'array': {
        c[i] = [];
        deepCopy(p[i], c[i]);
        break;
      }
      case 'object': {
        c[i] = {};
        deepCopy(p[i], c[i]);
        break;
      }
      default: {
        c[i] = p[i];
        break;
      }
    }
  }
  return c;
}

Notes on the deep copy and shallow copy can refer to the previously written "in the JS05 JS copy"

ES6 Inheritance

ES6 inside use classand extendsinherit the implementation is actually syntactic sugar inherited methods in ES5, which can be achieved instance properties, prototyping, static property inheritance

  1. Examples of the attribute class through classthe inside of the constructorinside superachieved
  2. Class through prototyping Object.setPrototypeOf(Child.prototype, Father.prototype)implementation (
  3. Static property class is through the Object.setPrototypeOf(Child, Father)realization of

Use inherited methods ES6, compared with inherited methods in ES5, at different points in the following main points:

(1) in order to achieve

ES5 inheritance, in essence, is the first instance of an object to create a sub-class this, and then add the parent class to thisthe top ( Parent.apply(this)).

ES6 inheritance mechanism is completely different subclasses did not start your own this, but you need to create an object instance of the parent class this(it must be called supermethod), then use the constructor subclass modify this.

(2) static and static properties

ES6 inherited methods can be inherited static methods and static properties of the parent class, and this is inherited methods ES5 can not be done.

(3) can not inherit the prototype property can only inherit prototyping

Since the classinternally defined in constructora method other than actually prototyping, and can not define a prototype property, so naturally inherited method can only be a prototype, the prototype can not inherit property

Enumerable of (4) a method Prototype

Because classinternally defined methods are not enumerable, that this behavior is inconsistent with ES5.

newthe process of

In an example of an object by the constructor ( new) process

let p = new Person()

The occurrence of the following procedures:

// 1 新建一个对象
let p = {};

// 2 修改p的__proto__属性,实现原型链的继承
p.__proto__ === Person.protype

// 3 将Person的作用域改为p,也就是说让Person中的this指向p,为p添加实例属性
Person.call(p)

// 4 返回p
return p

newOperation returns the default return value this, but an explicit return value, if the return value is the basic type , the return value is ignored, still return this, if the return value is a reference type , then directly back to the return value as a result of an object

Guess you like

Origin blog.csdn.net/duola8789/article/details/94740040