Home > Web Front-end > JS Tutorial > Detailed explanation of js object-oriented inheritance knowledge

Detailed explanation of js object-oriented inheritance knowledge

小云云
Release: 2018-02-05 09:35:23
Original
1450 people have browsed it

Speaking of this inheritance, friends who know object-oriented know that most OO languages ​​have two types, one is interface inheritance (only inherits method signatures); the other is implementation inheritance (inherits actual methods). This article mainly I would like to introduce to you the knowledge related to js object-oriented inheritance, and share the readers’ learning experience in understanding this knowledge point. Friends in need can refer to it. Hope it helps everyone.

However, there is no signature in js, so it can only implement inheritance, and it is implemented by the prototype chain. Let’s formally talk about inheritance in js

1. Prototype chain

Prototype chain: The main method to implement inheritance is to use prototypes to let one reference type inherit another reference type. Properties and methods.

Review: The relationship between constructors, prototypes, and instances

Each constructor has a prototype object (Person.prototype); the prototype object contains a pointer to the constructor (constructor ); Each instance contains a pointer to the prototype object (invisible _proto_ pointer)

How does the prototype chain come from?

The prototype object of a constructor is an instance of another constructor; the prototype object of this constructor will have an (invisible_proto_pointer) pointing to the prototype object of another constructor;

So what if another prototype object is another constructor instance? In this way, it progresses layer by layer to form a prototype chain; let’s take a closer look


    //第一个构造函数;有一个属性和一个原型方法
    function SuperType(){
        this.property=true;
    } 
    
    SuperType.prototype.getSuperValue=function(){
        return this.property
    }


    //第二个构造函数;目前有一个属性
    function SubType(){
        this.subproperty=false
    }
    
    //继承了SuperType;SubType原型成了SuperType的实例;实际就是重写SubType的原型对象;给SuperType原型对象继承了
    SubType.prototype=new SuperType()
    
    //现在这个构造函数有两个属性(一个本身的subproperty,一个继承的存在原型对象的property);两个方法(一个原型对象的getSubValue,一个原型对象的原型对象的getSuperValue)
    SubType.prototype.getSubValue=function(){
        return this.subproperty
    }
    
    var instance=new SubType()  //创建第二个构造函数的实例

    console.log(instance.getSuperValue())  //true 先查找instance这个实例有没有此方法;显然没有,再查找SubType原型对象有没有此方法;也没有,再查找SubType原型对象的原型对象;显然是存在的
Copy after login

Note: The constructor of instance now points to the constructor of SuperType; because the original SubType.prototype has been rewritten, its internal constructor also points to the constructor SuperType along with the constructor of the prototype object of SubType.prototype; As for how the prototype search mechanism works, please read the above code carefully. I believe you can do it.

1.1 Complete prototype

I have already mentioned some of it in the prototype section, so let’s talk about it again. . The complete prototype includes Object.

The default prototype of all functions is an instance of Object; each default prototype has a _proto_ pointer pointing to Object.prototype; therefore, custom types inherit methods such as toString and valueOf

The _proto_ pointer of Object.prototype points to null to end the prototype chain. Take the Person constructor as an example and look at the complete prototype chain diagram

1.2 Judgment of the relationship between prototype and instance

The first one uses the instanceof operator: Test the constructor that appears in the instance and prototype chain, and the result is true

The second method is to use the isPrototypeOf() method: As long as it is a prototype that has appeared in the prototype chain, it can be said to be an instance derived from the prototype chain Prototype


    console.log(instance instanceof Object)   //都为true
    console.log(instance instanceof SuperType)
    console.log(instance instanceof SubType)

   
    console.log(Object.prototype.isPrototypeOf(instance)) //都为true
    console.log(SuperType.prototype.isPrototypeOf(instance))
    console.log(SubType.prototype.isPrototypeOf(instance))
Copy after login

1.3 Define methods carefully

Note: Adding methods to the prototype object must be placed after the replacement prototype, because it is placed before the replacement prototype It cannot be found, and the prototype will be rewritten;

Note: When inheriting through the prototype chain, you cannot use object literals to create prototype methods, because the prototype chain will also be rewritten;


    function SuperType(){
        this.property=true;
    } 
    
    SuperType.prototype.getSuperValue=function(){
        return this.property
    }
    
    function SubType(){
        this.subproperty=false
    }
    
    //继承SuperType
    SubType.prototype=new SuperType()
    
    //使用字面量添加新方法,导致上一行无效   因为现在的原型替换了Object实例而非SuperType的实例,关系中断
    SubType.prototype={
       getSubValue:function(){
           return this.subproperty;
       },
       somOtherMethod:function(){
           return false
       }
    };

    var instance=new SubType()
    console.log(instance.getSuperValue())  //error
Copy after login

1.4 Problems with the prototype chain

1. Prototypes containing reference type values: When the instance is the prototype of another function, the reference type value will become the prototype Properties will be shared by instances of another function.


    function SuperType(){
       this.colors=["yellow","red","olive"]
    }

    function SubType(){
    }

    SubType.prototype=new SuperType()  //color实际上就是原型上的了

    var instance1=new SubType()
    instance1.colors.push("purple")
    var instance2=new SubType()

    console.log(instance1.colors==instance2.colors)  //true
Copy after login

2. When creating a subtype instance, parameters cannot be passed to the supertype constructor (there is no way to pass parameters to the supertype constructor without affecting all object instances). Constructor passes parameters)

2. Use the constructor

In order to solve the problems caused by reference type values ​​​​in the prototype, use the constructor to solve the problem

In subtype construction The function's internal call supertype constructor (a function is an object that executes code in a specific environment and can be called by apply or call)


    function SuperType(){
        this.color=["yellow","red","olive"]
    }

    function SubType(){
        //继承了SuperType
        SuperType.call(this)
    }

    var instance1=new SubType()
    instance1.color.push("purple")
    var instance2=new SubType()

    console.log(instance1.color)  //["yellow","red","olive","purple"]
    console.log(instance2.color)  //["yellow","red","olive"]


    //传递参数
    function SuperType(name){
       this.name=name
    }
    function SubType(){
        SuperType.call(this,"double")
        this.age=12
    }

    var instance1=new SubType()
    console.log(instance1.name)  //double
    console.log(instance1.age)  //12
Copy after login

Question: Just learn from the constructor, then The problem of the constructor cannot be avoided. The methods are all defined in the constructor, and the functions cannot be reused

3. Combination inheritance (commonly used is combination, the same as the combination of prototype and constructor)


    function SuperType(name){
        this.name=name;
        this.color=["yellow","red","olive"];
    }

    SuperType.prototype.sayName=function(){
        console.log(this.name);
    }
 
    function SubType(name,age){
        //继承属性,创建属性副本
        SuperType.call(this,name);
        this.age=age;
    }
    
    //继承属性和方法,只是原型中属性被后来的函数调用生成的属性副本遮盖
    SubType.prototype=new SuperType();

    alert(SubType.prototype.constructor)  //指向的是SuperType

    SubType.prototype.constructor=SubType; //将constructor回归到SubType构造函数身上
    SubType.prototype.sayAge=function(){
        console.log(this.age)
    }
    
    
    var instance1=new SubType("double",23)
    instance1.color.push("pink")
    console.log(instance1.color)     //["yellow","red","olive","pink"]
    instance1.sayName()         //double
    instance1.sayAge()          //23

    var instance2=new SubType("single",34)
    console.log(instance2.color)     //["yellow","red","olive"]
    instance2.sayName()         //single
    instance2.sayAge()          //34
Copy after login

There are other inheritances, take some time to write about them

1. Prototypal inheritance

Written by Crockford; you can use prototypes to be based on existing objects Create new objects without creating custom types


    function object(o){      //本质上object()函数对其中对象的浅复制
        function F(){}      //创建一个新的构造函数
        F.prototype=o      //构造函数原型为传入的对象
      return new F()      //返回构造函数的实例
    }

    var person={
        name:"double",
        friends:["tom","jack","mike"]
    }

    var person1=object(person)   //事实上为原型共享
    person1.name="grey"
    person1.friends.push("single")
    
    console.log(person1.friends)  //["tom", "jack", "mike", "single"]

    var person2=object(person)
    person2.name="red"
    console.log(person2.friends)   //["tom", "jack", "mike", "single"]
Copy after login

In order to standardize prototype inheritance, ES5 has Object.create() for convenience, which is available for IE9 and above; just want to This method can be used to keep one object similar to another object


    var person={
        name:"double",
        friends:["tom","jack","mike"]
    }

    var person1=Object.create(person)
    person1.name="single"
    person1.friends.push("singles")

    var person2=Object.create(person)

    console.log(person1.friends==person2.friends) //true

    //Object.create()接受两个参数,一个为作为新对象原型的对象,一个为新对象定义额外属性对象
    var person={
        name:"double",
        friends:["tom","jack","mike"]
    }

    var person1=Object.create(person,{
         name:{ 
            value:"single"  //每个属性都是通过自己描述符定义的
         }
    })
Copy after login

2. Parasitic inheritance

The idea is in the same vein as prototype inheritance. Create a function to encapsulate the inheritance process, enhance the object internally through methods, and return the object; use


function object(o){
       function F(){}
       F.prototype=o
       return new F()
    }

    function createPerson(original){
       var clone=object(original)   //继承原型
       clone.sayName=function(){ 
           alert("name")
       }
       return clone
    }

    var person={
       name:"double",
       friends:["single","tom","jack"]
    }

    var person1=createPerson(person)
    person1.sayName()  //name   引用类型值还是共享的
Copy after login

3 when mainly considering the object. 3. Parasitic combination inheritance

Combined inheritance is often used in inheritance, but the supertype constructor will be called twice; parasitic combined inheritance is to solve this problem


  function object(o){
     function F(){}
     F.prototype=o
     return new F()
  }


  function inheritPrototype(subType,superType){
     var prototype=object(superType)    //创建对象  (superType实例)
     prototype.constructor=subType     //增强对象
     subType.prototype=prototype      //指定对象  (原型赋予实例)
  }
  

   function SuperType(name,sex){
      this.name=name
      this.sex=sex
      this.colors=["red"]
   }

   SuperType.prototype.sayName=function(){
     alert(this.name)
   }

   function SubType(name,sex,age){
      SuperType.call(this,name,sex)
      this.age=age
   }


   inheritPrototype(SubType,SuperType)    //目前subType.prototype什么都没有
   SubType.prototype.sayAge=function(){   //为subType.prototype添加个方法
      alert(this.age)
   }

   var person1=new SubType("double","man",34)
   console.log(person1.name)  //SuperType 这是个Bug
   console.log(person1.sex)   //man
   console.log(person1.colors) //["red"]
   person1.sayAge()       //34
Copy after login

That’s it, almost It’s over. Thank you for your support of Script House. I hope the content we compiled can help you.

related suggestion:

Detailed explanation of JavaScript object-oriented inheritance_javascript skills

The above is the detailed content of Detailed explanation of js object-oriented inheritance knowledge. For more information, please follow other related articles on the PHP Chinese website!

source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template