Heim > Web-Frontend > js-Tutorial > Hauptteil

Einführung in JavaScript-Prototypen und Prototypkettenmethoden (Codebeispiele)

不言
Freigeben: 2019-01-10 10:59:44
nach vorne
2719 Leute haben es durchsucht

Dieser Artikel bietet Ihnen eine Einführung in JavaScript-Prototypen und Prototypkettenmethoden (Codebeispiele). Ich hoffe, dass er für Freunde hilfreich ist.

1. Frage

Wie kann man genau bestimmen, ob eine Variable ein Array ist?

Schreiben Sie ein Beispiel für die Vererbung von Prototypenketten.

Andere Möglichkeiten der Vererbungsimplementierung

es6 Was ist das zugrunde liegende Prinzip der Vererbung

Beschreiben Sie den Prozess der Neuanschaffung eines Objekts

Wie man die Prototypenkette in Zepto und verwendet andere Quellcodes

2. Wissenspunkte

2.1 Konstruktor

Funktionen: Beginnen Sie mit einem Großbuchstaben

function Foo(name,age){
    //var obj = {}
    //this = {}
    this.name = name;
    this.age = age;
    this.class = 'class1'
    // return this
}

var f1 = new Foo('liming',19);
Nach dem Login kopieren

Erweitern

var o = {} ist der syntaktische Zucker für var o = new Object()

var a = [] ist der syntaktische Zucker für var a = new Array()

Funktion Foo(){} entspricht var Foo = new Function(){}

2.2 Prototypenregeln

Fünf Regeln:

1. Alle Referenztypen (Objekte, Arrays, Funktionen) haben alle Objekteigenschaften, d. das ist ein gewöhnliches Objekt

3. Alle Funktionen haben Prototypattribute (explizite Prototypen) und sind auch gewöhnliche Objekte

4. Alle Referenztypen (Objekte, Arrays, Funktionen) __proto__ Wert zeigt auf Prototyp seines Konstruktors

5. Wenn die Variable selbst nicht über dieses Attribut verfügt, geht sie zu ihrem __proto__, um

for (var key in object) {
    //高级浏览器中已经屏蔽了来自原型的属性
    //建议加上判断保证程序的健壮性
    if (object.hasOwnProperty(key)) {
        console.log(object[key]);
    }
}
Nach dem Login kopieren

zu finden 2.3 Prototypenkette

obj.__ proto

.

proto __ ...Object.prototype === nullinstanceof wird zur Beurteilung verwendet, zu welchem ​​Konstruktor der Referenztyp gehört

obj caseob Foo

Tatsächliche Bedeutung: Bestimmen Sie, ob Foo.prototype in der Prototypenkette von obj ist

3. Frage-Antwort

3.1 So ermitteln Sie genau, ob eine Variable ein Array istarr-Instanz eines Arrays

3.2 Schreiben Sie ein Beispiel der Prototypkettenvererbung

Dom-Abfrage kapseln

function Elem(id){
    this.elem = document.getElementById(id);
};

Elem.prototype.html = function(val){
    var elem = this.elem;
    if (val) {
        elem.innerHTML = val;
        return this;
    }else{
        return elem.innerHTML;
    }
}

Elem.prototype.on = function(type,fun){
    var elem = this.elem;
    elem.addEventListener(type,fun);
    return this;
}

var p1 = new Elem('id1');
p1.html("test").on('click',function(){
    console.log('点击');
})
Nach dem Login kopieren

3.3 Andere Möglichkeiten der Vererbungsimplementierung

3.3.1 Prototypische Vererbung

        var obj = {
            0:'a',
            1:'b',
            arr:[1]
        }
        
        function Foo(arr2){
            this.arr2 = [1]
        }

        Foo.prototype = obj;

        var foo1 = new Foo();
        var foo2 = new Foo();

        foo1.arr.push(2);
        foo1.arr2.push(2);

        console.log(foo2.arr);  //[1,2]
        console.log(foo2.arr2); //[1]
Nach dem Login kopieren
Vorteile: Einfache Implementierung

Nachteile:

1. Parameter können nicht an den übergeordneten Klassenkonstruktor übergeben werden

2. Wenn neue zwei Objekte gleichzeitig verwendet werden, wenn a Wird das Referenztypattribut im Prototyp eines Objekts geändert, wird auch das Attribut des anderen Objekts geändert. Weil die Referenzeigenschaften des Prototypobjekts von allen Instanzen gemeinsam genutzt werden.

3.3.2 Strukturelle Vererbung

        function Super(b){
            this.b = b;
            this.fun = function(){}
        }
        function Foo(a,b){
            this.a = a;
            Super.call(this,b);
        }

        var foo1 = new Foo(1,2);
        console.log(foo1.b);
Nach dem Login kopieren

Vorteile: Sie können Parameter an die übergeordnete Klasse übergeben, und Unterklassen teilen nicht die Referenzattribute der übergeordneten Klasse

Nachteile: Funktion Eine Wiederverwendung kann nicht erreicht werden, jede Unterklasse hat neuen Spaß, zu viele beeinträchtigen die Leistung und das Prototypobjekt der übergeordneten Klasse kann nicht vererbt werden.

3.3.3 Kombinationsvererbung

function Super(){
    // 只在此处声明基本属性和引用属性
    this.val = 1;
    this.arr = [1];
}
//  在此处声明函数
Super.prototype.fun1 = function(){};
Super.prototype.fun2 = function(){};
//Super.prototype.fun3...
function Sub(){
    Super.call(this);   // 核心
    // ...
}
Sub.prototype = new Super();
Nach dem Login kopieren

Vorteile: Es gibt kein Problem beim Teilen von Referenzattributen, Parameter können übergeben werden und Funktionen können wiederverwendet werden

Nachteile: Die Attribute von Die übergeordnete Klasse wird zweimal instanziiert. Die übergeordnete Klasse der echten Instanz kann nicht abgerufen werden (es ist unmöglich zu unterscheiden, ob die Instanz von der übergeordneten Klasse erstellt wird oder nicht).

Optimierung:

         function Super(b){
            this.b = b;
            this.fun = function(){}
        }

        Super.prototype.c = function(){console.log(1111)}

        function Foo(a,b){
            this.a = a;
            Super.call(this,b);
        }


        Foo.prototype = Super.prototype;
        //修复构造函数:
        var foo1 = new Foo(1,2);
Nach dem Login kopieren

Nachteil: Es ist unmöglich zu unterscheiden, ob die Instanz von der übergeordneten Klasse erstellt wird oder nicht.

3.3.4 Durch Unterklassen erstellte parasitäre Kombinationsvererbung

         function Super(b){
            this.b = b;
        }

        Super.prototype.c = function(){console.log(1111)}

        function Foo(a,b){
            this.a = a;
            Super.call(this,b);
        }

        var f = new Function();
        f.prototype = Super.prototype;
        Foo.prototype = new f();
        //等同于 Foo.prototype = Object.create(Super.prototype);
        
        var foo1 = new Foo(1,2);
Nach dem Login kopieren

parasitiert den Prototyp der übergeordneten Klasse Das heißt, es wird in einen Prototyp eines leeren Objekts verpackt und dieses Objekt dann als Peototyp einer untergeordneten Klasse instanziiert.

Nachteile: Es ist unmöglich zu unterscheiden, ob eine Instanz von einer übergeordneten Klasse oder einer Unterklasse erstellt wird

Sie können den folgenden Code hinzufügen:

Foo.prototype.constructor = Foo
Nach dem Login kopieren

Diese Lösung kann nicht verwendet werden Für die obige kombinierte Optimierungsmethode werden die Änderungen gleichzeitig geändert, da sich die Unterklasse und die übergeordnete Klasse auf dasselbe Prototypobjekt beziehen.

Zusammenfassung:

Vererbung realisiert hauptsächlich die Wiederverwendung von Methoden und Attributen der übergeordneten Klasse durch Unterklassen.

Referenzeigenschaften vom Prototypobjekt werden von allen Instanzen gemeinsam genutzt, daher möchten wir vermeiden, Eigenschaften vom Prototyp zu erben.

Sie können die Attribute und Methoden des übergeordneten Klassenkonstruktors über die Aufruffunktion im Konstruktor erben, aber die auf diese Weise instanziierte Instanz speichert die übergeordneten Klassenmethoden mehrmals, was sich auf die Leistung auswirkt.

Durch kombinierte Vererbung verwenden wir Aufrufvererbungseigenschaften und die Prototypenvererbungsmethode, um die beiden oben genannten Probleme zu lösen. Das auf diese Weise instanziierte Objekt speichert jedoch zwei Kopien der Eigenschaften im Konstruktor der übergeordneten Klasse.

Das Erstellen eines neuen Objekts unter Verwendung des Prototyps der übergeordneten Klasse als Prototyp der Unterklasse löst das Problem der Mehrfachspeicherung, sodass die endgültige parasitäre Kombinationsvererbung die beste Vererbungsmethode ist. Ihr Nachteil besteht darin, dass sie problematischer ist schreiben.

3.3.6 Vererbungsimplementierung im Knotenquellcode

function inherits(ctor, superCtor) {
  ctor.super_ = superCtor;
  ctor.prototype = Object.create(superCtor.prototype, {
    constructor: {
      value: ctor,
      enumerable: false,
      writable: true,
      configurable: true
    }
  });
}; 

function Stream(){
    //...
}

function OutgoingMessage() {
  Stream.call(this);
  //...
}

inherits(OutgoingMessage, Stream);

OutgoingMessage.prototype.setTimeout = ...
Nach dem Login kopieren

Das Obige ist ein Beispiel für die Vererbung parasitärer Kombinationen.

1. Erben Sie die Eigenschaften im Stream-Konstruktor durch Aufruf im OutgoingMessage-Konstruktor.

2. Rufen Sie die Methode inherits auf, um die Eigenschaften im Stream-Prototyp zu erben.

3. Funktion, die den eigenen Prototyp von OutgoingMessage erweitert.

Die Object.create-Methode wird in der Inherits-Methode verwendet. Die Funktion dieser Methode besteht darin, ein neues Objekt über das angegebene Prototypobjekt und die angegebenen Attribute zu erstellen.

ctor.prototype=Object.create(superCtor.prototype,{.....});
Nach dem Login kopieren

Diese Methode erledigt tatsächlich die Arbeit in unserer obigen parasitären Kombinationsvererbung

var f = new Function();
f.prototype =superCtor.prototype;
return new f();
Nach dem Login kopieren

Die folgenden Parameter dienen zum Hinzufügen von Attributen zum Prototypobjekt, optionalen Attributen (nicht erforderlich), d. h. Dient sich selbst als Konstrukteur eines neu erstellten Objekts.

value: 表示constructor 的属性值;
writable: 表示constructor 的属性值是否可写;[默认为: false]
enumerable: 表示属性constructor 是否可以被枚举;[默认为: false]
configurable: 表示属性constructor 是否可以被配置,例如 对obj.a做 delete操作是否允许;[默认为: false]
Nach dem Login kopieren

3.4 So implementieren Sie die es6-Vererbung

Siehe meinen Artikel: https://segmentfault.com/a/11...

3.5 描述new一个对象的过程

  1. 创建一个对象

  2. {}._proto_ = 构造函数.prototype

  3. this指向这个对象

  4. 执行代码即对this赋值

  5. 返回this

3.6 zepto及其他源码中如何使用原型链

var Zepto = (function(){

    var $,zepto = {}
    
    // ...省略N行代码...
    
    $ = function(selector, context){
        return zepto.init(selector, context)
    }

    zepto.init = function(selector, context) {
        var dom
        
        // 针对参数情况,分别对dom赋值
        
        // 最终调用 zepto.Z 返回的数据
        return zepto.Z(dom, selector)
    }    

   fnction Z(dom, selector) {
      var i, len = dom ? dom.length : 0
     for (i = 0; i < len; i++) this[i] = dom[i]
      this.length = len
      this.selector = selector || ''
    }

   zepto.Z = function(dom, selector) {
     return new Z(dom, selector)
   }
  
    $.fn = {
        // 里面有若干个工具函数
    }
      
  
    zepto.Z.prototype = Z.prototype = $.fn
  
    
    // ...省略N行代码...
    
    return $
})()

window.Zepto = Zepto
window.$ === undefined && (window.$ = Zepto)
Nach dem Login kopieren

Das obige ist der detaillierte Inhalt vonEinführung in JavaScript-Prototypen und Prototypkettenmethoden (Codebeispiele). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:segmentfault.com
Erklärung dieser Website
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
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage