Heim > Web-Frontend > js-Tutorial > Hauptteil

Verstehen gängiger Muster und Prototypenketten

PHP中文网
Freigeben: 2017-06-20 09:37:30
Original
1752 Leute haben es durchsucht

Inhalt:

  • Mehrere Modi zum Erstellen von Objekten und des Erstellungsprozesses

  • Verständnis des Prototypkettenprototyps und prototype und Mehrere Implementierungen der Beziehung __proto__([[Prototype]])

  • Vererbung


1. Gemeinsame Muster und Prototypenkette Verstehen

a. Konstruktorerstellung

function Test() {// 
}
Nach dem Login kopieren

Prozess

  • Beim Erstellen einer Funktion wird standardmäßig ein Prototypattribut für Test erstellt, Test.prototype Enthält einen Zeiger, der auf Object.prototype

  • Prototyp zeigt, der standardmäßig einen Konstruktor hat, und andere Methoden in Test.prototype.constructor = Test

  • Prototyp Geerbt von Objekt


Beispiel
// 调用构造函数创建实例
var instance = new Test()
Nach dem Login kopieren

Die Instanz hier enthält einen Zeiger auf das Konstrukt Der Prototyp der Funktion, (Der Zeiger heißt hier __proto__ in Chrome, was auch gleich [[Prototype]] ist)


Beispiel

b. Prototypmodus
Aus dem oben Gesagten können wir erkennen, dass die standardmäßig erstellten Prototypeigenschaften nur über Konstruktoren und Eigenschaften verfügen, die von Object geerbt wurden. Der Prototypmodus besteht darin, Eigenschaften und Methoden zum Prototyp hinzuzufügen

Test.prototype.getName = ()=> {
    alert('name')
}
Nach dem Login kopieren

Zu diesem Zeitpunkt. Die Instanzinstanz ist Wir haben die getName-Methode, da der Instanzzeiger auf Test.prototype

instance.__proto__ === Test.prototype
Nach dem Login kopieren

zeigt, wie in der folgenden Abbildung gezeigt


897RVF ]E5@IX$) `IVJ3BOSY.png

Hier können wir erkennen, dass die Instanzinstanz und der Konstruktor durch den Prototyp prototype miteinander verbunden sind.

c. Kombinationsmodus
Wir verwenden diesen Modus am häufigsten. Es ist eigentlich eine andere Art, den Prototypmodus zu schreiben, mit nur einem kleinen Unterschied

function Test() {}

Test.prototype = {
    getName() {
        alert('name')
    }
}
Nach dem Login kopieren

Wir verwenden ihn oft direkt Beim Umschreiben der Prototyp-Methode wissen wir aus dem oben Gesagten, dass der Prototyp standardmäßig über ein eigenes Konstruktorattribut verfügt, das auf den Konstruktor selbst verweist. Was passiert also nach dem Umschreiben?

Test.prototype.constructor === Object 
// 而并不等于Test了// 因为重写以后相当于利用字面量方式创建一个实例对象,这个实例的构造函数是指向Object本身的
Nach dem Login kopieren

Natürlich können wir den Konstruktor auch manuell zuweisen

Test.prototype = {
    constructor: Test,
    getName() {
        alert('name')
    }
}
Nach dem Login kopieren

Dann wird es wieder Fragen gebenconstructorWas bringt das? Ich denke, die Bedeutung von Konstruktor besteht lediglich darin, den Konstruktor zu identifizieren, zu dem der Prototyp gehört.

Wenn ein bestimmtes Attribut abgerufen werden muss, wird es zuerst von der Instanz aus durchsucht. Wenn nicht, wird es entsprechend dem Prototyp durchsucht, auf den der Zeiger zeigt, und dann nach oben, bis der Zeiger der Instanz < ist 🎜> zeigt auf null und die Suche wird beendet. Beispiel: __proto__

// 1 读取nameinstance.name 

// 2 instance.__proto__ === Test.prototypeTest.prototype.name

// 3 Test.prototype.__proto__ === Object.prototypeObject.prototype.name

// 4Object.prototype.__proto__ === null
Nach dem Login kopieren
Wenn dieses Attribut gefunden wird, wird es direkt zurückgegeben, ohne die Suche fortzusetzen. Auch wenn der Attributwert null ist, wenn wir möchten Um die Suche fortzusetzen, können wir den Operator

verwenden. delete

Von hier aus können wir natürlich denken, dass

ein Konstruktor ist und ihre Prototypzeiger auf Array, Date, Function, String verweisen. Sie sind genau wie die Object.prototype, die ich hier definiert habe, aber sie sind nativ Test

d. Mehrere nützliche Methoden

  • Den Prototyp abrufen, auf den der Zeiger einer Instanz zeigt Object.getPrototypeOf()

    Object.getPrototypeOf(instance) === Test.prototype
    Nach dem Login kopieren
  • Bestimmen Sie, ob ein Attribut in der Instanz oder im Prototyp vorhanden ist, wie in der Abbildung gezeigt: hasOwnProperty


    NY~N} CNR`}8W %4QA$M8LFE4.png
  • Operator, unabhängig davon, ob das Attribut aufzählbar ist oder nicht in

    &#39;name&#39; in instance  // true
    &#39;getName&#39; in instance // true
    Nach dem Login kopieren
    unabhängig davon, ob das Attribut aufzählbar ist Beide geben in der Instanz und im Prototyp „true“ zurück. Wenn wir also feststellen müssen, ob ein Attribut in der Instanz oder im Prototyp vorhanden ist, gibt es zwei Methoden

    // 一种就是使用hasOwnProperty判断在实例中
    // 另一种判断在原型中
    instance.hasOwnProperty(&#39;getName&#39;) === false && &#39;getName&#39; in instance === true
    Nach dem Login kopieren
  • Operation Das Symbol ist das gleiche, aber es werden nur aufzählbare Eigenschaften aufgelistet. Der Fehler in der ie8-Version besteht darin, dass for ... in


    D (% S__GN8404{H9X6PW$DVK.png


    name是在实例中定义的,getName是在原型中定义的

  • Object.keys()则不一样,它返回一个对象上所有可枚举的属性,仅仅是该实例中的

    Object.keys(instance)// ["name"]
    Nach dem Login kopieren

e.总结
以上讨论了构造函数,原型和实例的关系:

  • 每个构造函数都有原型对象

  • 每个原型对象都有一个constructor指针指向构造函数

  • 每个实例都有一个__proto__指针指向原型

2.继承

其实是一个道理,这里我们不难想到,将Child.prototype指向parent实例,就是利用原型实现的继承,而为了每个实例都拥有各自的colors和name,也就是基础属性,在Child的构造函数中call调用了Parent的构造函数,相当于每次实例化的时候都初始化一遍colors和name,而不是所有实例共享原型链中的colors和name。

继承的实质是利用构造函数的原型 = 某个构造函数的实例,以此来形成原型链。例如

// 定义父类function Parent() {}Parent.prototype.getName = ()=> {
    console.log(&#39;parent&#39;)
}// 实例化父类let parent = new Parent()// 定义子类function Child() {}
Child.prototype = parent 
// 实例化子类let child = new Child()

child.getName() // parent// 此时
child.constructor === parent.constructor === Parent
Nach dem Login kopieren

a.最经典的继承模式

function Parent(name) {this.name = namethis.colors = [&#39;red&#39;]
}
Parent.prototype.getName = function() {console.log(this.name)
}// 实例化父类let parent = new Parent()function Child(age, name) {
    Parent.call(this, name)this.age = age
}
Child.prototype = parent 
// 实例化子类let child = new Child(1, &#39;aaa&#39;)
child.getName() // parent
Nach dem Login kopieren

这里会让我想到ES6中的class继承

class Parent {
    constructor(name) {this.name = namethis.colors = [&#39;red&#39;]
    }
    getName() {
        console.log(this.name)
    }
}class Child extends Parent {
    constructor(age, name) {super(name)
    }
}

let child = new Child(1, &#39;aaa&#39;)
child.getName() // parent
Nach dem Login kopieren

Das obige ist der detaillierte Inhalt vonVerstehen gängiger Muster und Prototypenketten. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:php.cn
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