Heim >Web-Frontend >js-Tutorial >Detaillierte Erläuterung des objektorientierten Vererbungswissens von js

Detaillierte Erläuterung des objektorientierten Vererbungswissens von js

小云云
小云云Original
2018-02-05 09:35:231483Durchsuche

Apropos Vererbung: Freunde, die sich mit Objektorientierung auskennen, wissen, dass die meisten oo-Sprachen zwei Arten haben: eine Schnittstellenvererbung (erbt nur Methodensignaturen) und die andere ist die Implementierungsvererbung (erbt hauptsächlich tatsächliche Methoden). Ich möchte Ihnen das Wissen im Zusammenhang mit der objektorientierten Vererbung von js vorstellen und die Lernerfahrung der Leser beim Verständnis dieses Wissenspunkts teilen. Freunde in Not können sich darauf beziehen. Ich hoffe, es hilft allen.

In js gibt es jedoch keine Signatur, es implementiert also nur die Vererbung und basiert auf der Prototypenkette. Lassen Sie uns offiziell über die Vererbung in js sprechen

1. Prototypenkette

Prototypenkette: Die Hauptmethode zur Vererbung besteht darin, Prototypen zu verwenden, um einem Referenztyp die Eigenschaften und Methoden eines anderen Referenztyps erben zu lassen.

Überprüfung: Die Beziehung zwischen Konstruktoren, Prototypen und Instanzen

Jeder Konstruktor hat ein Prototypobjekt (Person.prototype); das Prototypobjekt enthält einen Zeiger auf den Konstruktor (Konstruktor); ein Zeiger auf das Prototyp-Objekt (unsichtbarer _Proto_-Zeiger)

Woher kommt die Prototypenkette?

Das Prototypobjekt eines Konstruktors ist eine Instanz eines anderen Konstruktors; das Prototypobjekt dieses Konstruktors hat einen (unsichtbaren _Proto_zeiger), der auf das Prototypobjekt eines anderen Konstruktors zeigt; Das andere Prototypobjekt ist eine weitere Konstruktorinstanz. Auf diese Weise wird eine Prototypenkette gebildet. Schauen wir uns das genauer an Der Konstruktor der Instanz verweist nun auf den Konstruktor von SuperType. Da der ursprüngliche SubType.prototype neu geschrieben wurde, verweist sein interner Konstruktor zusammen mit dem Konstruktor des Prototypobjekts von SubType.prototype auf den Konstruktor Mechanismus funktioniert, bitte lesen Sie den obigen Code sorgfältig durch. Ich glaube, Sie können es schaffen.

1.1 Vollständiger Prototyp

Einige habe ich bereits im Abschnitt zum Prototyp erwähnt, oder sagen Sie es noch einmal. Der vollständige Prototyp enthält Object.

Der Standardprototyp aller Funktionen ist eine Instanz von Object; jeder Standardprototyp hat einen _proto_-Zeiger, der auf Object.prototype zeigt. Daher erben benutzerdefinierte Typen Methoden wie toString und valueOf
    //第一个构造函数;有一个属性和一个原型方法
    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原型对象的原型对象;显然是存在的

Der _proto_; Der Zeiger von Object.prototype zeigt auf null, um die Prototypenkette zu beenden. Nehmen Sie als Beispiel den Personenkonstruktor und sehen Sie sich das vollständige Prototypkettendiagramm an

1.2 Bestimmung der Beziehung zwischen Prototyp und Instanz

Der erste verwendet den Instanzenoperator: Testen Sie Instanzen und Konstruktoren, die in der Prototypenkette erscheinen, das Ergebnis ist wahr

Die zweite Methode ist die Verwendung von isPrototypeOf(): Solange es sich um einen Prototyp handelt, der in der Prototypenkette aufgetaucht ist Man kann sagen, dass es sich um eine aus der Prototypenkette abgeleitete Instanz handelt Prototype

1.3 Methoden sorgfältig definieren

Hinweis: Methoden zu Prototypobjekten hinzufügen muss nach dem Ersatzprototyp platziert werden, da er nach dem Ersatz platziert wird. Der Prototyp konnte zuvor nicht gefunden werden und der Prototyp wird neu geschrieben.

Hinweis: Bei der Vererbung über die Prototypenkette können Sie keine Objektliterale verwenden um Prototypenmethoden zu erstellen, da auch die Prototypenkette neu geschrieben wird;

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

1.4 Probleme mit Prototypenketten

1 : Wenn eine Instanz der Prototyp einer anderen Funktion ist, ändert sich der Referenztypwert. Als Eigenschaft des Prototyps wird er von Instanzen einer anderen Funktion gemeinsam genutzt.


    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
2. Beim Erstellen einer Subtyp-Instanz können keine Parameter an den Konstruktor des Supertyps übergeben werden (es gibt keine Möglichkeit, Parameter ohne Auswirkungen an den Supertyp-Konstruktor zu übergeben (alle Objektinstanzen). Der Konstruktor des Typs übergibt Parameter)

2. Verwenden Sie den Konstruktor

Um die durch Referenztypwerte im Prototyp verursachten Probleme zu lösen, verwenden Sie Der Konstruktor löst das Problem von


im Kind. Der interne Aufruf des Typkonstruktors ist der Supertypkonstruktor (eine Funktion ist ein Objekt, das Code in einer bestimmten Umgebung ausführt und durch Anwenden oder Aufrufen aufgerufen werden kann)

    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

Problem: Nur Konstruktor ausleihen, dann lässt sich das Konstruktorproblem nicht vermeiden, die Methoden sind im Konstruktor definiert und die Funktion kann nicht wiederverwendet werden

3. Kombinationsvererbung (üblicherweise wird Kombination verwendet, dasselbe wie die Kombination von Prototyp und Konstruktion)


    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
Es gibt andere Vererbungen, nehmen Sie sich einen Moment Zeit zum Schreiben über sie

1. Prototypische Vererbung

Geschrieben von Crockford; mit Hilfe von Prototypen können Sie neue Objekte basierend auf vorhandenen Objekten erstellen, ohne benutzerdefinierte Typen zu erstellen


    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

ES5 verfügt über Object.create() zur Standardisierung der Prototypenvererbung. Wenn Sie nur ein Objekt einem anderen Objekt ähneln möchten, können Sie diese Methode verwenden


2. Parasitäre Vererbung

    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"]
Die Idee ist die gleiche wie bei der prototypischen Vererbung. Erstellen Sie eine Funktion, um den Vererbungsprozess zu kapseln und das Objekt intern durch Methoden zu verbessern , und geben Sie das Objekt zurück; verwenden Sie


Kombinationsvererbung wird häufig bei der Vererbung verwendet. aber der Supertyp-Konstruktor wird zweimal aufgerufen; parasitäre Kombinationsvererbung soll dieses Problem lösen


Das ist es, es ist fast vorbei . Ich hoffe, dass die von uns zusammengestellten Inhalte Ihnen helfen können.
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   引用类型值还是共享的

Verwandte Empfehlungen:

Detaillierte Erläuterung der objektorientierten JavaScript-Vererbung_Javascript-Fähigkeiten

Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung des objektorientierten Vererbungswissens von js. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

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