Heim > Artikel > Web-Frontend > Eine kurze Analyse der Beziehung zwischen __proto__ und Prototyp in JavaScript
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!