JavaScript-Prototyp auf Funktionen beschränkt?

7

o.prototype = {...} funktioniert nur, wenn o eine Funktion ist. Angenommen, ich habe den folgenden Code

%Vor%

conf.a und conf.b ist OK und gibt die richtigen Werte zurück. Aber conf.d gibt 16 nicht zurück, sondern es wird undefiniert. Gibt es eine Lösung, die prototypbasierte Generalisierung kann auch auf diese Art von Objekten angewendet werden.

    
Neel Basu 21.01.2010, 17:20
quelle

2 Antworten

21

Sie verwechseln die prototype -Eigenschaft, die in Konstruktorfunktionen verwendet werden kann interne [[Prototype]] -Eigenschaft.

Alle Objekte haben diese interne Eigenschaft [[Prototype]] und nur die new Operator, wenn Sie es mit einer Konstruktorfunktion aufrufen, darf es setzen (über die [[Construct]] interne Operation).

Wenn Sie prototypische Vererbung mit Objektinstanzen haben möchten (ohne Konstruktoren zu verwenden), ist die Object.create Technik von Crockford was Sie wollen (diese Methode ist jetzt Teil der kürzlich genehmigten ECMAScript 5th Edition):

%Vor%

Im obigen Code hat conf seine drei Mitglieder, aber nur a und b werden physisch darauf existieren:

%Vor%

Weil d auf dem conf [[Prototype]] ( confProto ) existiert.

Die Eigenschaft Accessoren , . und [] sind verantwortlich für die Lösung der Eigenschaften, die bei Bedarf in der Prototypkette nachschlagen (durch die interne Methode [[Get]] ).

    
CMS 21.01.2010, 17:26
quelle
6

Es gibt tatsächlich zwei verschiedene Arten von "Prototypen" in JavaScript:

  1. Einer ist der "versteckte" Link, den jedes Objekt hat (verwenden wir [[Prototype]] , um diesen versteckten Link darzustellen). Objektliterale haben standardmäßig ihre versteckten Links, die auf Object.prototype zeigen, Funktionsobjekte haben ihre versteckte Verknüpfung auf Function.prototype und Arrays zeigen ihre auf Array.prototype . Diese versteckten Prototyp-Links sind nicht mit Eigenschaften mit dem Namen "prototype" verknüpft. Sie können diese versteckten Links nicht ändern, indem Sie o.prototype hinzufügen oder ändern.
  2. Eine andere ist, dass alle Funktionsobjekte automatisch eine spezielle Eigenschaft namens " prototype " haben. Dies ist hauptsächlich für die Verwendung von Konstruktoraufrufmustern.

[[Prototype]] wird für die Suche von Eigenschaften verwendet (wie das übergeordnete Element in der klassischen Hierarchie). Wenn eine Eigenschaft in einem Objekt nicht gefunden wird, wird stattdessen nach [[Prototype]] gesucht. Ein Verwendungsszenario: Wenn Sie beispielsweise allen Objekten eine Eigenschaft hinzufügen möchten, können Sie sie einfach zu Object.prototype hinzufügen, was automatisch für alle Objekte gilt, da alle Objekte irgendwie Object.prototype als [[Prototype]] chain root.

Läßt uns zur Funktion " prototype " der Objekte zurückkehren. Es ist nur nützlich, wenn es mit dem Operator new verwendet wird. Nehmen Sie das folgende Code-Snippet als Beispiel:

%Vor%

Was new F() oben tut, ist, zuerst ein neues Funktionsobjekt zu erstellen, die [[Prototype]] (versteckte Verknüpfung) dieses neu erstellten Funktionsobjekts auf F.prototype zu setzen und dann das neue Funktionsobjekt zurückzugeben. Dies ist wahrscheinlich das, was Sie bereits wissen, das für Funktionsobjekte funktioniert.

Denken Sie daran, dass ich gesagt habe, dass wir die [[Prototype]] von Objekten nicht ändern können? Naja, zumindest nicht direkt. Crockfords Funktion Object.create macht genau das, indem sie die Tatsache nutzt, dass der Operator new uns dabei helfen könnte [[Prototype]] für uns festzulegen. Wenn Sie also Object.create verwenden, müssen Sie absichtlich angeben, wohin der versteckte Link Ihres neuen Objekts zeigen soll. (etwas Gefühl wie die Angabe, wer ist Ihre Elternklasse)

In Ihrem Beispiel ist conf ein Objektliteral und conf.prototype ist nicht wirklich nützlich. Hier ist eine andere Version im klassischen Stil:

%Vor%

Im Vergleich zur Antwort von @CMS bevorzuge ich Object.create . Aber im Wesentlichen verwenden die 2 Stile den gleichen zugrundeliegenden Mechanismus, nur dass Object.create hilft, es aufzuräumen.

    
bryantsai 27.01.2010 13:20
quelle