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:
- Subclass performed inside the parent class (
call
/apply
changethis
), examples of attribute inheritance - Subclass
prototype
an instance of the parent class equals (new 父类
), examples of inherited attributes and attribute Prototype
ES6 inside use class
and extends
implementation 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 call
or apply
methods, 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.setPrototypeOf
method of
Using the Object.setPrototypeOf
method specified to make Child.prototype.__proto__
equal Father.prototype
, to achieve a prototype inherited property (the equivalent new
part 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 class
and extends
inheritance achieved:
class Father {
}
class Child extends Father {
constructor() {
super();
}
}
Note that, class
it 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.create
realization
Object.create
Inherited 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.setPrototypeOf
realization
Object.setPrototypeOf
And Object.create
all 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 object
function
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 class
and extends
inherit the implementation is actually syntactic sugar inherited methods in ES5, which can be achieved instance properties, prototyping, static property inheritance
- Examples of the attribute class through
class
the inside of theconstructor
insidesuper
achieved - Class through prototyping
Object.setPrototypeOf(Child.prototype, Father.prototype)
implementation ( - 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 this
the 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 super
method), 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 class
internally defined in constructor
a 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 class
internally defined methods are not enumerable, that this behavior is inconsistent with ES5.
new
the 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
new
Operation 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