2009-09-03 9 views
12

Ho appena iniziato a leggere su "Javascript di Douglas Crockford" Javascript ", dove spiega i tipi di base di Augmenting.Javascript Aumentare i tipi di base (prototipo ereditarietà) dubbio

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

Nel momento in cui dopo aver fatto questo, il addMethod diventa disponibile per tutti gli oggetti di base come String, Numero ecc che mi lascia perplesso

[1] perché questo accade quando non l'ho aggiunto a Object.prototype?

[2] Perché l'aggiunta di un metodo per Function.prototype si riflette in tutti gli oggetti di base?

Sono abbastanza nuovo per l'ereditarietà di javascript e prototipo. Quindi non so davvero se le mie domande sono sciocche?

+0

No, è l'implementazione di JavaScript del prototipo eredità che è sciocco. Il suo strano stile use-Function-as-constructor non offre nessuno dei potenziali vantaggi dei prototipi, pur essendo completamente diverso dall'ereditarietà basata sulla classe che la maggior parte dei programmatori comprende. È bello capire esattamente cosa stanno facendo i prototipi JavaScript, ma non aspettatevi un'illuminazione che renda ovvio il motivo per cui questo modello abbia un senso. Perché non è così. – bobince

risposta

16

probabilmente intendeva il momento in cui dopo aver fatto questo, l'addMethod diventa disponibile per tutti gli oggetti di base tipi di oggetti come stringa, numero ecc Questo è perché l'oggetto String è una funzione (ma oggetti creati da String non sono).

Ad esempio, dato

var s = ''; 

Si può fare

String.addMethod(...); 

ma non

s.addMethod(...); 

Una breve spiegazione del sistema di tipo JavaScript viene qui: fa

JavaScript non avere il normale concetto di classi. Invece, è possibile ottenere lo stesso risultato trasformando qualsiasi funzione in un costruttore inserendo la nuova parola chiave di fronte a esso quando viene richiamata.

es: dato

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

se lo si richiama come

var myObj = new MyFunction(10); 

creerà un oggetto chiamato myObj. Questo oggetto avrà una singola variabile membro chiamata myX. La funzione MyFunction è considerata il costruttore dell'oggetto (ed è memorizzata nella proprietà "costruttore"

(domanda bonus: cosa succederà se invochi la funzione sopra senza la nuova parola chiave, ovvero var x = MyFunction(10). sorprendere qualsiasi persona ragionevole)

Ora avete visto come qualsiasi funzione arbitraria può essere trasformata in un costruttore.Gli oggetti built-in sono esattamente gli stessi, gli oggetti stringa sono creati dalla funzione String, i numeri vengono creati dalla funzione Numero, ecc.

Proprio come quegli oggetti incorporati sono creati da funzioni, ciascuna di queste funzioni vengono creati anche dalla funzione "Funzione" (yikes!).

Ora su prototipi.

nell'esempio di cui sopra, se da qualche parte scrive

MyFunction.prototype.someNewMethod = function() {} 

tutti gli oggetti creati dal costruttore MyFunction/funzione apparirà ad avere una funzione di membro aggiuntivo chiamato someNewMethod. Puoi fare molte altre cose funky con i prototipi, come la sostituzione del prototipo o la sostituzione del prototipo del prototipo, ma non sono un esperto in questo.

+0

Giudicando da "this.prototype [nome]", penso che tu abbia esattamente ragione. –

+1

Puoi spiegarlo un po 'di più? Trovare il concetto difficile. –

+0

@erikkallen Come è un tipo di oggetto String (o qualsiasi altro tipo di oggetto base) una funzione? È come se l'oggetto String abbia un costruttore che è un oggetto Function? Per favore, spiegaci un po 'di più! – sriramptr

1

in JavaScript orientato agli oggetti, una funzione può servire come & costruttore della classe. Quindi, se la classe è stato chiamato MyObject, si potrebbe procedere come segue:

// 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() { 
    // ... 
} 

Nel tuo esempio, l'addMethod è stata aggiunta come un metodo di istanza alla classe Function, il che significa che è a disposizione di tutte le istanze di funzione. La funzione/classe/costruttore MyObject è un'istanza di Function, quindi puoi chiamare addMethod su di essa. Funziona con qualsiasi tipo di oggetto, ma non con HTMLElements in IE e altri browser.

1
  1. Le funzioni in JavaScript sono oggetti. Tutti gli oggetti hanno un collegamento nascosto in Object.prototype. Così per la prima dichiarazione:

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

    Lei ha dichiarato una funzione che è collegato a Function.prototype che a sua volta è legata alla Object.prototype.

  2. Per la seconda parte è solo un'assegnazione in cui si imposta la coppia valore nome su Object.prototype e verrà restituito il metodo add a tutti gli oggetti String, Number poiché è tutto dichiarato nel prototipo.
Problemi correlati