Heim > Web-Frontend > js-Tutorial > Hauptteil

Eine kurze Analyse der Beziehung zwischen __proto__ und Prototyp in JavaScript

零到壹度
Freigeben: 2018-03-22 11:37:15
Original
1131 Leute haben es durchsucht

Dieses Mal werde ich Ihnen eine kurze Analyse der Beziehung zwischen __proto__ und Prototyp in JavaScript geben. Folgen Sie dem Editor, um einen Blick darauf zu werfen.

1. Der __proto__ aller Konstruktoren/Funktionen zeigt auf Function.prototype, eine leere Funktion (Empty). Funktion)

Number.__proto__ === Function.prototype  // true
Boolean.__proto__ === Function.prototype // true
String.__proto__ === Function.prototype  // true
Object.__proto__ === Function.prototype  // true
Function.__proto__ === Function.prototype // true 
Array.__proto__ === Function.prototype   // true
RegExp.__proto__ === Function.prototype  // true
Error.__proto__ === Function.prototype   // true
Date.__proto__ === Function.prototype    // true
Nach dem Login kopieren

Es gibt insgesamt 12 integrierte (eingebaute) Konstruktoren/Objekte in JavaScript (JSON wurde in ES5 neu hinzugefügt). Hier sind 8 zugängliche Konstruktoren. Auf den Rest wie Global kann nicht direkt zugegriffen werden. Argumente werden nur von der JS-Engine erstellt, wenn die Funktion aufgerufen wird. Mathematik und JSON liegen in Form von Objekten vor, es sind keine neuen erforderlich. Ihr __proto__ ist Object.prototype. Wie folgt:

Math.__proto__ === Object.prototype  // true 
JSON.__proto__ === Object.prototype  // true
Nach dem Login kopieren

Zu den oben genannten „alle Konstruktoren/Funktionen“ gehören sicherlich auch benutzerdefinierte Konstruktoren/Funktionen. Wie folgt

// 函数声明
function Person() {}
// 函数表达式
var Man = function() {}
console.log(Person.__proto__ === Function.prototype) // true
console.log(Man.__proto__ === Function.prototype)    // true
Nach dem Login kopieren

Was bedeutet das?

Alle Konstruktoren stammen von Function.prototype, sogar der Root-Konstruktor Object und Function selbst. Alle Konstruktoren erben die Eigenschaften und Methoden von Function.prototype. Wie Länge, Aufruf, Anwenden, Binden (ES5).

Function.prototype ist auch der einzige Typ von XXX.prototype Prototyp der „Funktion“. Der Prototyp anderer Konstrukteure ist ein Objekt. Zum Beispiel:

console.log(typeof Function.prototype) // function
console.log(typeof Object.prototype)   // object
console.log(typeof Number.prototype)   // object
console.log(typeof Boolean.prototype)  // object
console.log(typeof String.prototype)   // object
console.log(typeof Array.prototype)    // object
console.log(typeof RegExp.prototype)   // object
console.log(typeof Error.prototype)    // object
console.log(typeof Date.prototype)     // object
console.log(typeof Object.prototype)   // object
Nach dem Login kopieren

Oh, oben wurde auch erwähnt, dass es sich um eine leere Funktion handelt. Schauen wir uns Alert(Function.prototype) an.

Nachdem wir nun wissen, dass das __proto__ aller Konstruktoren (einschließlich integrierter und benutzerdefinierter) Function.prototype ist, wer ist dann das __proto__ von Function.prototype?

Ich glaube, Sie haben alle gehört, dass Funktionen in JavaScript ebenfalls erstklassige Bürger sind. Wie können Sie das also zeigen? Wie unten gezeigt

console.log(Function.prototype.__proto__ === Object.prototype) // true
Nach dem Login kopieren

Dies zeigt, dass alle Konstruktoren auch gewöhnliche JS-Objekte sind und Attribute zum Konstruktor hinzugefügt/entfernt werden können. Gleichzeitig erbt es auch alle Methoden von Object.prototype: toString, valueOf, hasOwnProperty usw.

Wer ist der __proto__ von Object.prototype?

Object.prototype.__proto__ === null  // true
Nach dem Login kopieren

hat die Spitze erreicht und ist null.

2. Das __proto__ aller Objekte zeigt auf den Prototyp seines Konstruktors

Das Obige testet das __proto__ aller integrierten Konstruktoren und benutzerdefinierten Konstruktoren wie folgt Schauen Sie sich an, auf wen das __proto__ der Instanzobjekte all dieser Konstruktoren verweist?

Schauen Sie sich zuerst den integrierten Konstruktor der JavaScript-Engine an

var obj = {name: 'jack'}
var arr = [1,2,3]
var reg = /hello/g
var date = new Date
var err = new Error('exception')
console.log(obj.__proto__ === Object.prototype) // true
console.log(arr.__proto__ === Array.prototype)  // true
console.log(reg.__proto__ === RegExp.prototype) // true
console.log(date.__proto__ === Date.prototype)  // true
console.log(err.__proto__ === Error.prototype)  // true
Nach dem Login kopieren

Schauen Sie sich dann den benutzerdefinierten Konstruktor an, hier wird eine Person definiert

function Person(name) {
this.name = name
}
var p = new Person('jack')
console.log(p.__proto__ === Person.prototype) // true
Nach dem Login kopieren

p ist Person Bei Objekten zeigt der interne Prototyp von p immer auf den Prototyp seines Konstruktors Person.

Jedes Objekt verfügt über ein Konstruktorattribut und sein Konstruktor kann abgerufen werden, sodass die folgenden gedruckten Ergebnisse ebenfalls identisch sind

function Person(name) {
this.name = name
}
var p = new Person('jack')
console.log(p.__proto__ === p.constructor.prototype) // true
Nach dem Login kopieren

Die obige Person fügt seinem Prototyp keine Attribute oder Methoden hinzu. Fügen Sie hier eine getName-Methode

function Person(name) {
this.name = name
}
// 修改原型
Person.prototype.getName = function() {}
var p = new Person('jack')
console.log(p.__proto__ === Person.prototype) // true
console.log(p.__proto__ === p.constructor.prototype) // true
Nach dem Login kopieren

zu ihrem Prototyp hinzu. Sie können sehen, dass p.__proto__, Person.prototype und p.constructor.prototype alle identisch sind, das heißt, sie zeigen alle auf dasselbe Objekt .

Wenn Sie den Prototyp auf andere Weise festlegen, ist das Ergebnis etwas anders

function Person(name) {
this.name = name
}
// 重写原型
Person.prototype = {
getName: function() {}
}
var p = new Person('jack')
console.log(p.__proto__ === Person.prototype) // true
console.log(p.__proto__ === p.constructor.prototype) // false
Nach dem Login kopieren

Person.prototype wird hier direkt neu geschrieben (Hinweis: Das vorherige Beispiel dient zum Ändern des Prototyps) . Die Ausgabe zeigt, dass p.__proto__ immer noch auf Person.prototype verweist, nicht auf p.constructor.prototype.

Dies ist auch leicht zu verstehen. Was Person.prototype zugewiesen wird, ist ein Objektliteral {getName: function(){}}, der Konstruktor eines mithilfe von Objektliteralen definierten Objekts zeigt auf den Root-Konstruktor Object, Object.prototype ist ein leeres Objekt {}, {} ist natürlich dasselbe wie {getName: function(){}} ist nicht gleich. Wie folgt:

var p = {}
console.log(Object.prototype) // 为一个空的对象{}
console.log(p.constructor === Object) // 对象直接量方式定义的对象其constructor为Object
console.log(p.constructor.prototype === Object.prototype) // 为true,不解释
Nach dem Login kopieren

Das im obigen Code verwendete __proto__ wird derzeit in IE6/7/8/9 nicht unterstützt. In IE9 können Sie Object.getPrototypeOf(ES5) verwenden, um den internen Prototyp eines Objekts abzurufen.

var p = {}
var __proto__ = Object.getPrototypeOf(p)
console.log(__proto__ === Object.prototype) // true
Nach dem Login kopieren

Das obige ist der detaillierte Inhalt vonEine kurze Analyse der Beziehung zwischen __proto__ und Prototyp in JavaScript. 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