Maison > interface Web > js tutoriel > Explication détaillée des connaissances sur l'héritage orienté objet js

Explication détaillée des connaissances sur l'héritage orienté objet js

小云云
Libérer: 2018-02-05 09:35:23
original
1479 Les gens l'ont consulté

En parlant de cet héritage, les amis qui connaissent l'orientation objet savent que la plupart des langages OO ont deux types, l'un est l'héritage d'interface (hérite uniquement des signatures de méthode) et l'autre est l'héritage d'implémentation (hérite principalement des méthodes réelles). Je voudrais vous présenter les connaissances liées à l'héritage orienté objet js et partager l'expérience d'apprentissage des lecteurs dans la compréhension de ce point de connaissance. Les amis dans le besoin peuvent s'y référer. J'espère que cela aide tout le monde.

Cependant, il n'y a pas de signature dans js, donc il n'implémente que l'héritage et s'appuie sur la chaîne de prototypes. Parlons formellement de l'héritage en js

1. Chaîne de prototypes

Chaîne de prototypes : la méthode principale pour obtenir l'héritage consiste à utiliser des prototypes pour laisser un type de référence hériter d'un autre type de référence.

Révision : La relation entre les constructeurs, les prototypes et les instances

Chaque constructeur a un objet prototype (Person.prototype) ; l'objet prototype contient un pointeur vers le constructeur (constructor ) ; un pointeur vers l'objet prototype (pointeur _proto_ invisible)

D'où vient la chaîne prototype ?

L'objet prototype d'un constructeur est une instance d'un autre constructeur ; l'objet prototype de ce constructeur aura un (pointeur _proto_ invisible) pointant vers l'objet prototype d'un autre constructeur ;

Et si ; l'autre objet prototype est une autre instance de constructeur ? De cette façon, il progresse couche par couche pour former une chaîne de prototypes, regardons de plus près


    //第一个构造函数;有一个属性和一个原型方法
    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原型对象的原型对象;显然是存在的
Copier après la connexion

Remarque : Le Le constructeur d'instance pointe désormais vers le constructeur de SuperType ; comme le SubType.prototype original a été réécrit, son constructeur interne pointe également vers le constructeur ainsi que le constructeur de l'objet prototype de SubType.prototype quant à la manière dont le prototype recherche ; le mécanisme fonctionne, veuillez lire attentivement le code ci-dessus, je pense que vous pouvez le faire

1.1 Prototype complet

J'en ai déjà mentionné quelques-uns dans la section prototype, ou répétez-le. Le prototype complet inclut Object.

Le prototype par défaut de toutes les fonctions est une instance de Object ; chaque prototype par défaut a un pointeur _proto_ pointant vers Object.prototype ; par conséquent, les types personnalisés héritent de méthodes telles que toString et valueOf

Le _proto_ le pointeur de Object.prototype pointe vers null pour terminer la chaîne de prototypes. Prenez le constructeur Person comme exemple, jetez un œil au schéma de chaîne complet du prototype

1.2 Détermination de la relation entre le prototype et l'instance

Le premier utilise l'opérateur instanceof : Testez les instances et les constructeurs qui apparaissent dans la chaîne de prototypes, le résultat est vrai

La deuxième méthode consiste à utiliser isPrototypeOf() : Tant qu'il s'agit d'un prototype qui est apparu dans la chaîne de prototypes , on peut dire qu'il s'agit d'une instance dérivée de la chaîne de prototypes 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))
Copier après la connexion

1.3 Définir soigneusement les méthodes

Remarque : ajouter des méthodes aux objets prototypes doit être placé après le prototype de remplacement, car il est placé après le remplacement. Le prototype n'a pas pu être trouvé avant et le prototype sera réécrit

Remarque : lors de l'héritage via la chaîne de prototypes, vous ne pouvez pas utiliser de littéraux d'objet ; pour créer des méthodes prototypes, car la chaîne de prototypes sera également réécrite


    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
Copier après la connexion

1.4 Problèmes avec les chaînes de prototypes

1. : Lorsqu'une instance est le prototype d'une autre fonction, la valeur du type référence changera. En tant que propriété sur le prototype, elle sera partagée par les instances d'une autre fonction.


    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
Copier après la connexion

2. Lors de la création d'une instance de sous-type, les paramètres ne peuvent pas être transmis au constructeur du supertype (il n'y a aucun moyen de transmettre des paramètres au constructeur du supertype sans affecter toutes les instances d'objet). Le constructeur du type passe les paramètres)

2. Utilisez le constructeur

Afin de résoudre les problèmes causés par les valeurs de type référence​​dans le prototype, utilisez le constructeur pour résoudre le problème de

chez l'enfant L'appel interne du constructeur de type est le constructeur de supertype (une fonction est un objet qui exécute du code dans un environnement spécifique et peut être appelé par apply ou 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
Copier après la connexion

Problème : il suffit d'emprunter le constructeur, alors le problème du constructeur ne peut être évité, les méthodes sont définies dans le constructeur et la fonction ne peut pas être réutilisée

3. Héritage combiné (la combinaison est couramment utilisée, la même que la combinaison du prototype et de la construction)


    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
Copier après la connexion

Il existe d'autres héritages, prenez un moment pour écrire à leur sujet

1. Héritage prototypique

Écrit par Crockford ; à l'aide de prototypes Vous pouvez créer de nouveaux objets basés sur des objets existants sans créer de types personnalisés


    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"]
Copier après la connexion

ES5 a Object.create() pour standardiser l'héritage des prototypes. Pratique, IE9 et supérieur sont disponibles ; si vous souhaitez simplement conserver un objet similaire à un autre objet, cette méthode peut être utilisée


    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"  //每个属性都是通过自己描述符定义的
         }
    })
Copier après la connexion

2. Héritage parasite

L'idée est la même que celle de l'héritage prototypique Créer une fonction pour encapsuler le processus d'héritage, améliorer l'objet en interne via des méthodes. , et renvoie l'objet ; utilisez


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   引用类型值还是共享的
Copier après la connexion
< lorsque vous considérez principalement l'objet 🎜>3 L'héritage de combinaison parasite

L'héritage de combinaison est souvent utilisé dans l'héritage, mais le constructeur de supertype sera appelé deux fois ; l'héritage de combinaison parasite est pour résoudre ce problème


  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
Copier après la connexion
Ça y est, c'est presque fini. . J'espère que le contenu que nous avons compilé pourra vous aider.

Recommandations associées :

Explication détaillée des compétences JavaScript orientées objet successoral_javascript

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal