Maison  >  Article  >  interface Web  >  Explication détaillée de l'héritage en JavaScript

Explication détaillée de l'héritage en JavaScript

黄舟
黄舟original
2017-03-04 15:57:101213parcourir

Le concept d'héritage js

jsLes deux méthodes d'héritage suivantes sont couramment utilisées dans :

Héritage de chaîne de prototypes (héritage entre objets)
Héritage classique (héritage entre constructeurs)

Puisque js n'est pas un véritable langage orienté objet comme java, js est basé sur des objets, il n'a pas de concept de classes . Par conséquent, si vous souhaitez implémenter l'héritage, vous pouvez utiliser le mécanisme prototype de js ou utiliser les méthodes apply et call pour implémenter

Dans les langages orientés objet, nous utilisons pour créer une définition automatique des objets. Cependant, tout dans js est un objet, alors comment créer un objet personnalisé ? Cela nécessite l'utilisation du prototype de js :

On peut simplement considérer prototype comme un modèle, et les objets personnalisés nouvellement créés sont tous des copies de ce modèle (prototype) ( En fait, ce n'est pas une copie mais un lien, mais ce lien est invisible. Il y a un pointeur __Proto__ invisible à l'intérieur de l'objet nouvellement instancié, pointant vers l'objet prototype).

jsVous pouvez simuler les fonctions de la classe d'implémentation via des constructeurs et des prototypes. De plus, jsLa mise en œuvre de l'héritage de classe s'appuie également sur la chaîne de prototypes.

L'héritage prototypique et l'héritage de classe

类式继承 consiste à appeler le constructeur de supertype à l'intérieur du constructeur de sous-type.

L'héritage de classe strict n'est pas très courant. Il est généralement utilisé en combinaison :

function Super(){
    this.colors=["red","blue"];
}

function Sub(){
    Super.call(this);
}

原型式继承 consiste à créer un nouvel objet à l'aide d'objets existants et à convertir le prototype de. la sous-classe Pointer vers la classe parent équivaut à rejoindre la chaîne de prototypes de la classe parent

Héritage de la chaîne de prototypes

Pour que la sous-classe hérite des attributs (y compris les méthodes) de la classe parent , vous devez d'abord définir une fonction de structure. Ensuite, affectez la nouvelle instance de la classe parent au prototype du constructeur. Le code est le suivant :

<script>
    function Parent(){
        this.name = &#39;mike&#39;;
    }

    function Child(){
        this.age = 12;
    }
    Child.prototype = new Parent();//Child继承Parent,通过原型,形成链条

    var test = new Child();
    alert(test.age);
    alert(test.name);//得到被继承的属性
    //继续原型链继承
    function Brother(){   //brother构造
        this.weight = 60;
    }
    Brother.prototype = new Child();//继续原型链继承
    var brother = new Brother();
    alert(brother.name);//继承了Parent和Child,弹出mike
    alert(brother.age);//弹出12
</script>

Il reste encore un maillon manquant dans l'héritage de la chaîne de prototypes ci-dessus, qui est Object, et tous les constructeurs héritent de Object. L'héritage Object s'effectue automatiquement et ne nécessite pas que nous héritions manuellement. Alors quelle est leur affiliation ?

Détermination de la relation entre les prototypes et les instances

La relation entre les prototypes et les instances peut être déterminée de deux manières. Opérateurs instanceof et isPrototypeof() méthodes :

alert(brother instanceof Object)//true
alert(test instanceof Brother);//false,test 是brother的超类
alert(brother instanceof Child);//true
alert(brother instanceof Parent);//true

Tant qu'il s'agit d'un prototype qui apparaît dans la chaîne de prototypes, on peut dire qu'il s'agit du prototype de l'instance dérivée de la chaîne de prototypes. Par conséquent, la méthode isPrototypeof() renverra également true

Dans js, la fonction héritée est appelée le super type (la classe parent, la classe de base est également acceptable), et la fonction héritée est appelée le sous-type (sous-classe, classe dérivée). Il y a deux problèmes principaux avec l'utilisation de l'héritage prototypique :
Premièrement, la réécriture littérale du prototype rompra la relation, en utilisant le prototype du type référence, et le sous-type ne peut pas transmettre de paramètres au supertype.

Les pseudo-classes résolvent le problème du partage de références et de l'impossibilité de transmettre des paramètres de super types. Nous pouvons utiliser la technologie du "constructeur emprunté"

Constructeur emprunté (héritage de classe)

<script>
    function Parent(age){
        this.name = [&#39;mike&#39;,&#39;jack&#39;,&#39;smith&#39;];
        this.age = age;
    }

    function Child(age){
        Parent.call(this,age);
    }
    var test = new Child(21);
    alert(test.age);//21
    alert(test.name);//mike,jack,smith
    test.name.push(&#39;bill&#39;);
    alert(test.name);//mike,jack,smith,bill
</script>

Bien qu'emprunter des constructeurs résout les deux problèmes que nous venons de mentionner, sans prototype, la réutilisation est impossible, nous avons donc besoin du 原型链 借用构造函数 modèle, appelé héritage combiné

Héritage combiné

<script>
    function Parent(age){
        this.name = [&#39;mike&#39;,&#39;jack&#39;,&#39;smith&#39;];
        this.age = age;
    }
    Parent.prototype.run = function () {
        return this.name  + &#39; are both&#39; + this.age;
    };
    function Child(age){
        Parent.call(this,age);//对象冒充,给超类型传参
    }
    Child.prototype = new Parent();//原型链继承
    var test = new Child(21);//写new Parent(21)也行
    alert(test.run());//mike,jack,smith are both21
</script>

L'héritage combiné est une méthode d'héritage couramment utilisée. L'idée derrière elle est d'utiliser la chaîne de prototypes pour hériter des propriétés et des méthodes du prototype, et d'emprunter des constructeurs pour hériter des propriétés d'instance. De cette manière, la réutilisation des fonctions est réalisée en définissant des méthodes sur le prototype, et chaque instance est garantie d'avoir ses propres attributs. Utilisation de

call() : Appelez une méthode d'un objet pour remplacer l'objet actuel par un autre objet.

call([thisObj[,arg1[, arg2[, [,.argN]]]]])

Héritage prototypique

Ce type d'héritage utilise des prototypes pour créer de nouveaux objets basés sur des objets existants sans créer de types personnalisés. Il est appelé 原型式继承

<script>
     function obj(o){
         function F(){}
         F.prototype = o;
         return new F();
     }
    var box = {
        name : &#39;trigkit4&#39;,
        arr : [&#39;brother&#39;,&#39;sister&#39;,&#39;baba&#39;]
    };
    var b1 = obj(box);
    alert(b1.name);//trigkit4

    b1.name = &#39;mike&#39;;
    alert(b1.name);//mike

    alert(b1.arr);//brother,sister,baba
    b1.arr.push(&#39;parents&#39;);
    alert(b1.arr);//brother,sister,baba,parents

    var b2 = obj(box);
    alert(b2.name);//trigkit4
    alert(b2.arr);//brother,sister,baba,parents
</script>
L'héritage prototypique crée d'abord un constructeur temporaire à l'intérieur de la fonction

, puis utilise l'objet transmis comme prototype de ce constructeur, et renvoie enfin une nouvelle instance de ce type temporaire. obj()

Héritage parasite

Cette méthode d'héritage combine le modèle d'usine de prototype dans le but d'encapsuler le processus de création.

<script>
    function create(o){
        var f= obj(o);
        f.run = function () {
            return this.arr;//同样,会共享引用
        };
        return f;
    }
</script>
Petits problèmes avec l'héritage combiné

L'héritage combiné est le modèle d'héritage le plus couramment utilisé

, mais le supertype de l'héritage combiné sera appelé deux fois lors de l'utilisation Une fois lors de la création d'un ; sous-type, et une autre fois à l'intérieur du constructeur de sous-type js

<script>
    function Parent(name){
        this.name = name;
        this.arr = [&#39;哥哥&#39;,&#39;妹妹&#39;,&#39;父母&#39;];
    }

    Parent.prototype.run = function () {
        return this.name;
    };

    function Child(name,age){
        Parent.call(this,age);//第二次调用
        this.age = age;
    }

    Child.prototype = new Parent();//第一次调用
</script>
Le code ci-dessus est l'héritage combiné précédent, donc l'héritage combiné parasite résout le problème de deux appels.

Héritage combiné parasite

<script>
    function obj(o){
        function F(){}
        F.prototype = o;
        return new F();
    }
    function create(parent,test){
        var f = obj(parent.prototype);//创建对象
        f.constructor = test;//增强对象
    }

    function Parent(name){
        this.name = name;
        this.arr = [&#39;brother&#39;,&#39;sister&#39;,&#39;parents&#39;];
    }

    Parent.prototype.run = function () {
        return this.name;
    };

    function Child(name,age){
        Parent.call(this,name);
        this.age =age;
    }

    inheritPrototype(Parent,Child);//通过这里实现继承

    var test = new Child(&#39;trigkit4&#39;,21);
    test.arr.push(&#39;nephew&#39;);
    alert(test.arr);//
    alert(test.run());//只共享了方法

    var test2 = new Child(&#39;jack&#39;,22);
    alert(test2.arr);//引用问题解决
</script>
appeler et appliquer

les fonctions globales

et apply peuvent être utilisées pour changer le pointeur de call dans la fonction , comme suit : this

// 定义一个全局函数
    function foo() {
        console.log(this.fruit);
    }

    // 定义一个全局变量
    var fruit = "apple";
    // 自定义一个对象
    var pack = {
        fruit: "orange"
    };

    // 等价于window.foo();
    foo.apply(window);  // "apple",此时this等于window
    // 此时foo中的this === pack
    foo.apply(pack);    // "orange"
Ce qui précède est l'explication détaillée des méthodes d'héritage en JavaScript. Pour plus de contenu connexe, veuillez faire attention au site Web PHP chinois (www.php.cn) !


Déclaration:
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