Heim  >  Artikel  >  Web-Frontend  >  Eine kurze Analyse der Beziehung zwischen __proto__ und Prototyp in JavaScript

Eine kurze Analyse der Beziehung zwischen __proto__ und Prototyp in JavaScript

零到壹度
零到壹度Original
2018-03-22 11:37:151115Durchsuche

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

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

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

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

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

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

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

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

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

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

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

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,不解释

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

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!

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