2009-09-03 2 views
12

Ich habe gerade angefangen zu lesen auf Douglas Crockfords "Javascript The Good Teile", wo er über Augmentieren Grundtypen erklärt.Javascript Augmenting Grundtypen (Prototyp Vererbung) Zweifel

Function.prototype.addMethod=function(name,func) { 
    this.prototype[name]=func; 
    return this; 
}; 

In dem Moment, nachdem dies zu tun, die addMethod wird für alle Basisobjekte wie String verfügbar, Anzahl etc. Das ist mir

verwirrt verlässt

[1] Warum passiert wenn ich es nicht hinzugefügt habe Object.prototype?

[2] Warum ein Verfahren zur Function.prototype Zugabe in allen grundlegenden Objekten reflektiert wird?

Ich bin ziemlich neu für Javascript und prototypische Vererbung. Also weiß ich nicht wirklich, ob meine Fragen albern sind?

+0

Nein, es ist JavaScript-Implementierung der Prototyp-Vererbung, die albern ist. Sein seltsamer using-Function-as-Constructor-Stil bietet Ihnen keinen der potenziellen Vorteile von Prototypen und unterscheidet sich trotzdem grundlegend von der klassenbasierten Vererbung, die die meisten Programmierer verstehen. Es ist schön, genau zu verstehen, was JavaScript-Prototypen tun, aber erwarten Sie keine Epiphanie, die es offensichtlich macht, warum dieses Modell sinnvoll ist. Weil es nicht so ist. – bobince

Antwort

16

er wahrscheinlich der Moment, nachdem tun dies bedeutete, wird die addMethod für alle grundlegenden Objekte Objekttypen wie String, Anzahl etc. Dies liegt daran, dass die String-Objekt eine Funktion (aber Objekte, die von String erstellt wurden, sind nicht).

ZB gegeben

var s = ''; 

Sie

tun können
String.addMethod(...); 

aber nicht

s.addMethod(...); 

Eine kurze Erklärung des Typs System JavaScript kommt hier:

JavaScript tut nicht haben das normale Konzept von Klassen. Stattdessen können Sie etwas Ähnliches erreichen, indem Sie jede Funktion in einen Konstruktor umwandeln, indem Sie das neue Schlüsselwort davor setzen, wenn es aufgerufen wird.

Z. B: gegeben

function MyFunction(x) { this.myX = x; } 

, wenn Sie es aufrufen, wie

var myObj = new MyFunction(10); 

wird es ein Objekt erstellen, genannt myObj. Dieses Objekt wird eine einzelne Mitgliedsvariable namens myX haben. Die Funktion MyFunction wird als Konstruktor des Objekts betrachtet (und in der Eigenschaft "constructor" gespeichert.

(Bonusfrage: Was passiert, wenn Sie die obige Funktion ohne das neue Schlüsselwort aufrufen, zB var x = MyFunction(10). Die Antwort wird wahrscheinlich überrasche jede vernünftige Person.)

Jetzt hast du gesehen, wie jede beliebige Funktion in einen Konstruktor umgewandelt werden kann.Die eingebauten Objekte sind genau gleich, Stringobjekte werden von der Funktion String erzeugt, Zahlen werden von der Funktion erzeugt Nummer usw.

Genau wie diese eingebauten Objekte durch Funktionen erzeugt werden, wird jede dieser Funktionen auch von der "Funktion" -Funktion erstellt (yikes!).

Jetzt zu den Prototypen.

in dem obigen Beispiel, wenn Sie irgendwo

schreiben
MyFunction.prototype.someNewMethod = function() {} 

alle vom MyFunction Konstruktor erstellte Objekte/Funktion erscheint eine zusätzliche Member-Funktion haben someNewMethod genannt. Sie können viele andere flippige Dinge mit Prototypen machen, wie das Ersetzen des Prototyps oder das Ersetzen des Prototyps des Prototyps, aber ich bin kein Experte darin.

+0

Nach 'this.prototype [name]' zu urteilen, denke ich, dass Sie genau richtig sind. –

+1

Kannst du das etwas mehr erklären? Das Konzept schwierig finden. –

+0

@erikkallen Wie ist der String-Objekttyp (oder ein anderer Basisobjekttyp) eine Funktion? Ist es so, dass das String-Objekt einen Konstruktor hat, der ein Function-Objekt ist? Bitte erläutern Sie das ein bisschen mehr! – sriramptr

1

In objektorientiertem JavaScript kann eine Funktion als Klasse &-Konstruktor dienen. Also, wenn Sie Ihre Klasse MyObject benannt wurde, können Sie folgendes tun können:

// create a class/constructor 
function MyObject() { 
    // ... 
} 

// add a static method to the MyObject class 
MyObject.someFunction = function() { 
    // ... 
} 

// add an instance method to the MyObject Class 
MyObject.prototype.someFunction = function() { 
    // ... 
} 

In Ihrem Beispiel wurde die addMethod als Instanz Methode, um die Funktionsklasse hinzugefügt, was bedeutet, es auf alle Instanzen Funktion zur Verfügung steht. Die MyObject-Funktion/class/constructor ist eine Instanz von Function. Sie können also addMethod aufrufen. Dies funktioniert mit den meisten Objekttypen, aber nicht HTMLElements in IE und einigen anderen Browsern.

1
  1. Funktionen in JavaScript sind Objekte. Alle Objekte haben einen versteckten Link zu Object.prototype. So für die erste Erklärung:

    > `Function.prototype.addMethod=function(name,func) {} 
    

    Sie haben eine Funktion deklariert, die Function.prototype verknüpft ist, die sich auf Object.prototype verbunden ist.

  2. Für den zweiten Teil ist es nur eine Zuweisung, bei der Sie das Name-Wert-Paar auf den Object.prototype setzen und die Methode add allen String-, Number-Objekten zurückgeben, da alles im Prototyp deklariert ist.