Heim  >  Artikel  >  Web-Frontend  >  Detaillierte Erklärung der Vererbung in JavaScript

Detaillierte Erklärung der Vererbung in JavaScript

黄舟
黄舟Original
2017-03-04 15:57:101211Durchsuche

Das Konzept der js-Vererbung

jsDie folgenden zwei Vererbungsmethoden werden häufig verwendet in:

Prototypkettenvererbung (Vererbung zwischen Objekten)
Klassische Vererbung (Vererbung zwischen Konstruktoren)

Da js keine echte objektorientierte Sprache wie java ist, ist js objektbasiert und hat keine Klassen. Konzept. Wenn Sie also die Vererbung implementieren möchten, können Sie den Prototypmechanismus von js verwenden oder die Methoden apply und call verwenden, um

zu implementieren. In objektorientierten Sprachen verwenden wir um eine automatische Definition von Objekten zu erstellen. Allerdings ist alles in js ein Objekt. Wie erstellt man also ein benutzerdefiniertes Objekt? Dies erfordert die Verwendung des Prototyps von js:

Wir können prototype einfach als Vorlage betrachten, und die neu erstellten benutzerdefinierten Objekte sind alle Kopien dieser Vorlage (prototype) ( Tatsächlich Es handelt sich nicht um eine Kopie, sondern um einen Link, aber dieser Link ist unsichtbar. Im neu instanziierten Objekt befindet sich ein unsichtbarer __Proto__-Zeiger, der auf das Prototypobjekt zeigt.

jsSie können die Funktionen der Implementierungsklasse durch Konstruktoren und Prototypen simulieren. Darüber hinaus jsDie Implementierung der Klassenvererbung basiert auch auf der Prototypenkette.

Prototypische Vererbung und Klassenvererbung

类式继承 besteht darin, den Supertyp-Konstruktor innerhalb des Subtyp-Konstruktors aufzurufen.

Strikte Klassenvererbung ist nicht sehr verbreitet. Sie wird normalerweise in Kombination verwendet:

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

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

原型式继承 besteht darin, mithilfe vorhandener Objekte ein neues Objekt zu erstellen und den Prototyp davon zu konvertieren Das Verweisen der Unterklasse auf die übergeordnete Klasse entspricht dem Beitritt zur Prototypenkette der übergeordneten Klasse

Vererbung der Prototypenkette

Damit die Unterklasse die Attribute (einschließlich Methoden) der übergeordneten Klasse erbt , müssen Sie zunächst eine Strukturfunktion definieren. Weisen Sie dann die neue Instanz der übergeordneten Klasse dem Prototyp des Konstruktors zu. Der Code lautet wie folgt:

<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>

Es fehlt noch ein Glied in der obigen Prototyp-Kettenvererbung, nämlich Object, und alle Konstruktoren erben von Object. Die Vererbung Object erfolgt automatisch und erfordert keine manuelle Vererbung. Was ist also ihre Zugehörigkeit?

Bestimmung der Beziehung zwischen Prototypen und Instanzen

Die Beziehung zwischen Prototypen und Instanzen kann auf zwei Arten bestimmt werden. Operatoren instanceof und isPrototypeof() Methoden:

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

Solange es sich um einen Prototyp handelt, der in der Prototypenkette erscheint, kann man sagen, dass es sich um den Prototyp der aus der Prototypenkette abgeleiteten Instanz handelt. Daher gibt die Methode isPrototypeof() auch true

zurück. In js wird die geerbte Funktion als Supertyp bezeichnet (übergeordnete Klasse, Basisklasse ist ebenfalls akzeptabel) und die geerbte Funktion wird als Supertyp bezeichnet Untertyp (Unterklasse, abgeleitete Klasse). Es gibt zwei Hauptprobleme bei der Verwendung der Prototypenvererbung:
Erstens wird durch das wörtliche Umschreiben des Prototyps die Beziehung unterbrochen, wobei der Prototyp des Referenztyps verwendet wird und der Untertyp keine Parameter an den Obertyp übergeben kann.

Pseudoklassen lösen das Problem der Referenzfreigabe und der Unfähigkeit, Parameter von Supertypen zu übergeben. Wir können die „geliehene Konstruktor“-Technologie verwenden

Geliehener Konstruktor (Klassenvererbung)

<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>

Obwohl das Ausleihen von Konstruktoren die beiden gerade genannten Probleme löst, ist eine Wiederverwendung ohne einen Prototyp unmöglich, daher benötigen wir das 原型链+借用构造函数 Muster, das als kombinierte Vererbung bezeichnet wird

Kombinierte Vererbung

<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>

Kombinierte Vererbung ist eine häufig verwendete Vererbungsmethode. Die Idee dahinter besteht darin, die Prototypenkette zum Erben von Prototypeigenschaften und -methoden zu verwenden und Konstruktoren zum Erben von Instanzeigenschaften auszuleihen. Auf diese Weise wird die Wiederverwendung von Funktionen durch die Definition von Methoden im Prototyp erreicht, und jede Instanz verfügt garantiert über ihre eigenen Attribute. Verwendung von

call(): Rufen Sie eine Methode eines Objekts auf, um das aktuelle Objekt durch ein anderes Objekt zu ersetzen.

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

Prototypische Vererbung

Diese Art der Vererbung verwendet Prototypen, um neue Objekte basierend auf vorhandenen Objekten zu erstellen, ohne benutzerdefinierte Typen zu erstellen >Prototypische Vererbung erstellt zunächst einen temporären Konstruktor innerhalb der Funktion 原型式继承, verwendet dann das übergebene Objekt als Prototyp dieses Konstruktors und gibt schließlich eine neue Instanz dieses temporären Typs zurück.

<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>
Parasitäre Vererbung

obj()Diese Vererbungsmethode kombiniert den Prototyp + das Fabrikmuster, um den Erstellungsprozess zu kapseln.

Kleine Probleme mit kombinierter Vererbung

Kombinierte Vererbung ist das am häufigsten verwendete Vererbungsmuster
<script>
    function create(o){
        var f= obj(o);
        f.run = function () {
            return this.arr;//同样,会共享引用
        };
        return f;
    }
</script>
, aber der Supertyp der kombinierten Vererbung wird während der Verwendung zweimal aufgerufen Subtyp und ein anderes Mal im Subtyp-Konstruktor

Der obige Code ist die vorherige kombinierte Vererbung, sodass die parasitäre kombinierte Vererbung das Problem von zwei Aufrufen löst. js

Parasitäre kombinierte Vererbung
<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>

Aufrufen und Anwenden

Globale Funktionen
<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>
und

können verwendet werden, um den Zeiger von

in der Funktion zu ändern , wie folgt:

applycall Das Obige ist die detaillierte Erklärung der Vererbungsmethoden in JavaScript. Weitere verwandte Inhalte finden Sie auf der chinesischen PHP-Website (www.php.cn)! 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"

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn