Korrekte Prototypkette für Funktion

7

Was ist die korrekte Ausgabe des folgenden Programms (entspricht dem ECMA-Standard)?

%Vor%

Chrome und IE6 stimmen zu:

%Vor%

und dann abstürzt.

Mozilla-Ausgaben:

%Vor%

Sind beide richtig? Es scheint, dass der Mozilla besser ist, aber dass die beste Ausgabe ist

%Vor%     
Claudiu 20.12.2008, 10:33
quelle

4 Antworten

9

Was Sie hier machen, ist nicht wirklich die Prototyp-Kette - Diese Frage könnte Ihnen helfen zu verstehen, was tatsächlich vor sich geht. Ich habe mich nicht die ECMA-Spezifikation angesehen, aber hier ist meine Meinung zu dem Thema:

  • Funktion ist der Konstruktor von Funktionsobjekten

  • Function.prototype ist der Prototyp, von dem alle Funktionsobjekte übernommen werden. Er kann Eigenschaften wie Aufruf und anwenden enthalten allen Funktion -Instanzen gemeinsam; Die von Ihnen überprüften Implementierungen waren insofern konsistent, als sie selbst als Funktionsobjekt implementiert sind (wie einige darauf hingewiesen haben, die ECMA-Spezifikation erfordert dies)

  • Function.prototype.prototype macht nicht wirklich viel Sinn, ist aber als Function.prototype als Funktionsobjekt implementiert (das möglicherweise verwendet werden kann) als Konstruktor) sollte es zumindest existieren; Objekte, die mit Function.prototype als Konstruktor erstellt werden, würden seine Eigenschaften erben - aber da es keinen Grund geben sollte, etwas Wahnsinniges zu tun, setzen Sie es auf null , undefined oder ein leeres Objekt ist sinnvoll

  • Function.prototype.prototype.prototype wird in aller Wahrscheinlichkeit undefiniert sein: Function.prototype.prototype strong> sollte etwas ohne Eigenschaften sein ( null , undefined oder ein leeres Objekt) und definitiv kein Funktionsobjekt; Daher sollte seine Prototyp -Eigenschaft undefiniert sein oder sogar einen Fehler ausgeben, wenn versucht wird, auf sie zuzugreifen

Hoffe, das hilft;)

    
Christoph 20.12.2008, 14:31
quelle
12

Funktionsprototyp

Von ECMAScript-Sprache Spezifikation :

  

15.3.3.1 Function.prototype

     

Der Anfangswert von Function.prototype ist   das Funktionsprototyp - Objekt (Abschnitt   15.3.4).

     

15.3.4 Eigenschaften des Funktionsprototypobjekts

     

Die Funktion   Prototyp-Objekt ist selbst eine Funktion   Objekt (seine [[Klasse]] ist "Funktion")   das, wenn es aufgerufen wird, akzeptiert alle   Argumente und gibt undefined zurück. Das   Wert des internen [[Prototyp]]   Eigenschaft des Funktionsprototyps   Objekt ist das Objekt Prototyp-Objekt   (Abschnitt 15.3.2.1).

     

Es ist eine Funktion mit einem "leeren Körper";   Wenn es aufgerufen wird, kehrt es nur zurück   nicht definiert. Der Funktionsprototyp   Objekt hat keinen Wert   Eigenes Eigentum; Wie auch immer, es   erbt die ValueOf-Eigenschaft von der   Objektprototyp Objekt.

Ich bekomme diese Ausgabe:

  • Opera: function () {[nativer Code]}
  • Chrome: Funktion Empty () {}
  • IE7: Funktionsprototyp () {[systemeigener Code]}
  • FF3: function () {}

Chrome und IE7 haben ihre Funktionen benannt, Opera und IE7 sagen Ihnen, dass es die Implementierung nicht aufdeckt. Sie sind sich alle einig:

%Vor%

Vergleiche das mit:

%Vor%

Function.prototype.prototype

Ich erhalte undefined von Opera und IE7, null von Chrome und [Objektobjekt] von FF3. Wer hat Recht? Da "Das Prototyp-Objekt Funktion selbst ist ein Function-Objekt" sollte es nicht ein Zirkelbezug zu sich selbst sein? Um den Zirkelbezug zu vermeiden, haben sie verschiedene Wege gewählt. Ich weiß nicht, ob es einen Standard dafür gibt oder ob es an der Implementierung liegt, aber ich denke, ein Objekt hat Recht. Übrigens, hier sehen Sie den Unterschied zwischen dem internen [[Prototyp]] und dem öffentlichen Prototyp in Aktion, wie Sie in einer früheren Frage gefragt haben!

Function.prototype.prototype == Object.prototype

Dies ist falsch, weil es nicht das gleiche Objekt ist. Siehe oben.

Function.prototype.prototype.prototype

Nur FF gibt Ihnen eine Antwort wegen ihrer Implementierung von Function.prototype.prototype gibt ein Objekt zurück.

Ich stimme zu, dass Ihre vorgeschlagene Ausgabe mehr Logik aussieht.

Sie sind sich einig:

%Vor%     
some 20.12.2008 13:01
quelle
4

Um Ihre Frage direkt zu beantworten: Mozilla hat Recht. Nicht nur, weil Brendan Eich für Mozilla arbeitet, sondern weil das der einzig richtige Weg ist. Lass uns über Details gehen:

  • Jeder Konstruktor ist eine Funktion.
  • Jede Funktion hat prototype -Eigenschaft, die zum Konstruieren von Objekten verwendet werden kann.
  • Der Prototyp ist ein Objekt (ein Wörterbuch). Einzelne Objekte delegieren Methoden / Eigenschaften an ihre jeweiligen Prototypen.
  • Im Falle einer Funktion ist das Prototyp-Objekt speziell - es implementiert funktionsspezifische Methoden und Eigenschaften. Der Typ / die Klasse dieses Objekts ist nicht definiert und nicht direkt verfügbar.
  • Dieses Prototyp-Objekt kann nicht Object noch Object.prototype .
  • sein

Lassen Sie mich auf die letzte Aussage eingehen. Wenn es falsch ist, können wir die Funktion im Benutzercode wie folgt neu erstellen:

%Vor%

Wir können beobachten, dass new Object() keine neuen Methoden oder Eigenschaften definiert und versuchen kann, Object.prototype direkt mit demselben Ergebnis zu verwenden.

Zusammenfassung: Der Prototyp der Funktion ist nicht Object noch Object.prototype . Es ist ein ganz besonderes Objekt. Dies ist ein weiterer Grund, warum wir keine Funktion im Benutzercode neu erstellen können.

EDIT: für weitere Details zu Prototypen siehe diese Antwort .

    
Eugene Lazutkin 20.12.2008 16:34
quelle
2

Ich weiß, dass dieser Beitrag etwas alt ist, aber ich habe im Internet nach Informationen zu diesem Thema gesucht und dachte mir, dass ich das posten würde, was ich gefunden habe. Die Prototypeigenschaft ist für Konstruktorfunktionen. Sie können das Prototypobjekt von Objekten zuweisen, die Sie mit dem neuen Schlüsselwort erstellen.

Jedes Objekt in JavaScript hat ein Prototyp-Objekt, aber viele Implementierungen geben Ihnen keinen direkten Zugriff darauf oder erlauben Ihnen, es nach der Objekt-Erstellung einzustellen. In FireFox können Sie über die Eigenschaft " __proto__ " auf dieses Objekt zugreifen.

Im Folgenden habe ich eine Version Ihres Codes mit der Eigenschaft " __proto__ ". Der Abschnitt über die Prototypkette von Function stimmt mit dem überein, was Sie erwartet haben.

%Vor%

Ausgabe in FireFox ist:

%Vor%     
patorjk 22.01.2010 06:28
quelle