<>js Prototype chain in ,6 The way of inheritance and its cases

We know how to face people (OOP) The three characteristics of : inherit , encapsulation , polymorphic ( heavy load , rewrite )

js It's not strictly object-oriented language , because js Object oriented is based on prototype chain .

<> Prototype chain

The prototype chain is composed of __proto__ A chain like structure connected in series . Every function has one prototype attribute , There are also __proto__, Each object has only one
__proto__ attribute ; In general, we put the attribute method constructor in the , Put the method in the prototype below , Object's
__proto__ That points to the constructor prototype, The end point of the prototype chain is Object.prototype, Up again Object.prototype.__proto__=null

1. Instance has no concrete constructor
let obj={} console.log(obj.__proto__== Object.prototype) //true console.log(
Object.prototype.__proto__) //null
2. The constructor of an instance is a custom constructor
function Persion(){}// Constructor let p=new Persion()// example console.log(p.__proto__==
Persion.prototype) //true console.log(Persion.prototype.__proto__==Object.
prototype) //true console.log(Object.prototype.__proto__) //null
3. The constructor of an instance is a built-in constructor
let p = new Array() console.log(p.__proto__ == Array.prototype) //true console.
log(Array.__proto__ ==Function.prototype)//true console.log(Function.__proto__
== Function.prototype)//true ,Function Is a constructor , It's also an object console.log(Function.prototype
.__proto__==Object.prototype)//true console.log(Object.prototype.__proto__)

Function The constructor of a constructor is itself ,Function Access as instantiated object Function Constructors are available , therefore Function.__proto__ Can be accessed Function.prototype; Any function inherits Function All methods and properties of , and Function Is a built-in constructor , It's also an object , It's all inheritance Object All properties and methods of ,Function.prototype.__proto__=Object.prototype

First write one here Persion Superclass , This class has a property called name, There is an example method introduce, There is a prototype approach hobby
function Parent(name){ this.name=name this.introduce=function(){ console.log(
"my name is"+this.name) } } Parent.prototype.hobby=function(hobby){ console.log(
this.name+" like "+hobby) }
<>1. Prototype chain inheritance

The prototype of a subclass points to an instance of the parent class ( Subclass .prototype=new Superclass ())
function Child() {} // Subclass // Child.prototype.sleep=function(){ //
console.log(this.name+"is sleeping") // }1 Child.prototype = new Parent("yzh")
// In order not to destroy the prototype chain , take Male Of constructor Point to itself Child.prototype.constructor=Child Child.
prototype.sleep=function(){ console.log(this.name+" is sleeping") }//2 Parent.
prototype.eat=function(){ console.log(this.name+" is eating") } var child=new
Child() console.log(Child) child.introduce() child.hobby(" sing ") child.sleep()
child.eat() console.log(child instanceof Parent) //true console.log(child
instanceof Child) //true
notes : If Male Prototype method sleep Put in 1 Position , Will report a mistake child.sleep is not a function, Put in 2 position , output yzh is

The characteristics of this method of inheritance :

* The relationship between the subclass and the parent class is directional , An instance is an instance of a subclass , It is also an instance of the parent class
* Prototype method or property added by parent class , All subclasses can be accessed
* Easy to use
shortcoming :

* If you want to add a property or method to a subclass , Only in new Parent()
after , It cannot be placed in a constructor , Code example above , If the new method is placed before changing the direction of the subclass prototype , After changing the direction, the new method will be useless , Subclass prototype Already pointed to the parent class
All instances of subclass , Share all parent properties , Subclasses cannot have their own properties , If there are multiple instances , One of the instances modified the value of the parent reference type , Then all instances will change , For example, I just want to take an example of eat The method is changed to “is
eating apple”, The method will change in all instances
* You can't inherit more , Because it changed the direction of the prototype chain , Cannot point to more than one parent class , Therefore, it can only be inherited by itself
* When creating a subclass , Cannot pass a parameter to a parent constructor , Because after changing the direction of the prototype chain of the subclass , The properties and methods of the subclass are invalid
<>2. Constructive inheritance (call,apply inherit )

hold All properties and methods of the parent object , Copy into child object
function Child(name){ Parent.call(this,name) } var child=new Child("yzh")
console.log(child.name) //yzh child.introduce() child.hobby("sing") console.log(
childinstanceof Parent) //false console.log(child instanceof Child) //true
advantage :

* It solves the problem that the subclasses in the prototype chain inheritance share the parent class attribute
* The created subclass instance can pass parameters to the parent class
* Multiple inheritance can be realized ,call Changing the parent class's this
shortcoming :

* An instance is an instance of a subclass , The parent class of is not
* Only instance properties and methods of the parent class can be inherited , Methods on a parent prototype cannot be inherited
Function reuse is not possible , Each subclass has a copy of the properties and methods of the parent function , When child call Parent On the method ,Parent Internal this It's pointing to child,Parent Internal this The properties and methods on are copied to child above , If every instance of a subclass copies the properties and methods of the parent class , It takes up a lot of memory , And when the method of the parent class changes , A subclass instance that has already been created cannot update methods , Because the original parent method has been copied as its own method .
<>3. Combinatorial inheritance ( Prototype chain inheritance and construction inheritance )
function Child(name) { Parent.call(this,name) // Constructive inheritance , Call the parent class the second time } // Prototype chain inheritance Child.
prototype=new Parent() Child.prototype.constructor=Child var child=new Child(
"yzh") // Instances of subclasses pass parameters to the parent class , Calling the parent class for the first time console.log(child.name) child.introduce() child.
hobby("sing") console.log(child instanceof Parent) //true console.log(child
instanceof Child) //true
advantage : It combines the advantages of prototype chain inheritance and construction inheritance

* Subclass can pass parameters to parent class
* An instance is an instance of a subclass , It is also an instance of the parent class
* There is no common parent class reference property between multiple instances
* Instances can inherit the properties and methods of the parent instance , You can also inherit properties and methods from prototypes
shortcoming : This method calls the constructor of the parent class twice , Two instances are generated , The same properties exist in both instances and prototypes

<>4. Copy inheritance
function Child(name){ var parent = new Parent(name); for(var key in parent){
Child.prototype[key] = parent[key]; } } var child=new Child("yzh") console.log(
child.name) //yzh child.introduce() child.hobby("sing") console.log(child
instanceof Parent) //false console.log(child instanceof Child) //true
advantage :

* Support multiple inheritance
shortcoming :

* Cannot get method of parent class that cannot be enumerated , This method uses for in To traverse Parent Properties in , For example, multi box checked attribute , This is the property that cannot be enumerated
* It's inefficient , High memory consumption
<>5. Parasitic combinatorial inheritance

Parasitic combinatorial inheritance : Inheriting properties by borrowing constructors , Methods are inherited through a hybrid form of the prototype chain .

thinking : It is not necessary to call the constructor of the parent class in order to specify the prototype of the subclass , All we need is a copy of the parent prototype . Essentially , It is to use parasitic inheritance to inherit the prototype of the parent class , Then assign the result to the prototype of the subclass

In fact, it does not need to instantiate the parent class constructor , You can also get the properties and methods of the parent class , It is to directly instantiate a copy of a temporary parent class , Implement prototype chain inheritance
function Child(name) { Parent.call(this,name) // Constructive inheritance } (function(){ // Create a temporary class
var Temp=function(){} Temp.prototype=Parent.prototype // The prototype of a subclass points to an instance of the parent class
Child.prototype=new Temp() })() var p=new Child("yzh") console.log(p.name)//yzh
p.hobby("sing")//yzh like sing p.introduce()//my name is yzh
advantage : Combine all the advantages of composite inheritance , This method is perfect

<>6.ES6 inherit
class Parent{ constructor(name){ this.name=name } introduce(){ console.log("my
name is " + this.name) } hobby(hobby){ console.log(this.name + " like " + hobby)
} } class Child extends Parent{ constructor(name,age){ super(name)
// Constructive inheritance , Inheritable Parent Property on constructor this.age=age } } var p = new Child("yzh") p.introduce(
) //my name is yzh p.hobby("apple")//yzh like apple console.log(p instanceof
Parent) // true console.log(p instanceof Child) //true
We use it es6 The method of writing makes the object more clear , It's more like object-oriented programming ; It is used in this method extends and super
Two keywords , In subclass constructor Call in method super method , Used to inherit the parent class this object

<> Prototype drag
<style type="text/css"> *{ margin: 0; padding: 0; } body,html{ width: 100%;
height: 100%; } .box{ width: 100px; height: 100px; background-color:
palevioletred; position: absolute; color: #fff; display: flex; justify-content:
center; align-items: center; padding: 10px; } </style> <div class="box" id="box"
>box1 Unlimited scope </div> <div class="box" id="box2">box2 Limited scope </div> // Drag without limits class
Drag{ constructor(ele){ this.box=document.querySelector(ele) this.addHandler() }
addHandler(){ this.box.onmousedown=(e)=>{ let _x=e.offsetX // The distance from the upper boundary of the distance element when the mouse is pressed let
_y=e.offsetY e.preventDefault() // Sliding and lifting events are bound to document upper document.onmousemove=(e)=>
{ let _left=e.clientX-_x //e.clientX The distance of the mouse from the top of the browser let _top=e.clientY-_y //
console.log(_left,_top) // Distance from document this.move(_left,_top) } document.onmouseup=()
=>{ document.onmousemove=null } } } move(_left,_top){ this.box.style.left=_left+
'px' this.box.style.top=_top+'px' } } // Limited scope inherit Drag class limitDrag extends Drag
{ constructor(ele) { super(ele) } // rewrite move function move(_left,_top){ if(_left<0)_left=
0 if(_top<0)_top=0 if(_left>document.body.offsetWidth-this.box.offsetWidth)
_left=document.body.offsetWidth-this.box.offsetWidth if(_top>document.body.
offsetHeight-this.box.offsetHeight) _top=document.body.offsetHeight-this.box.
offsetHeightthis.box.style.left=_left+'px' this.box.style.top=_top+'px' } } new
Drag('#box') new limitDrag('#box2')

©2020 ioDraw All rights reserved
0.96OLED display -4 Line SPI explain C++11 of std::function,std::bind,std::placeholdersJavaScript study ( Function declaration and parameters )QTabWidget Style sheet settings The project passed idea Package and publish to tomcat The server postman Interface test get timestamp and MD5 encryption react Background management configuration route and sidebar :python Simple game code -10 Minutes Python Write a snake game , simple You know? Python What does the foundation include ? Learn something ?10 individual Python Introduction to crawler