2009-12-26 9 views
35

La mia domanda è:questa funzione all'interno

function Foo() 
{ 
    this.foo = "bar"; // <- What is "this" here? 
} 

Da quello che posso dire che dipende da come viene utilizzato Foo, vale a dire come un costruttore o come una funzione. Cosa può this essere in diverse circostanze?

risposta

46

La parola chiave this fa riferimento all'oggetto a cui appartiene la funzione o all'oggetto window se la funzione non appartiene a nessun oggetto.

'utilizzato nel codice OOP, per fare riferimento alla classe/oggetto la funzione appartiene Ad esempio:

function foo() { 
    this.value = 'Hello, world'; 

    this.bar = function() { 
     alert(this.value); 
    } 
} 

var inst = new foo(); 
inst.bar(); 

This avvisi Hello, world

È possibile manipolare quale oggetto this riferisce a usando le funzioni apply() o call(). (Una caratteristica molto molto utile, a volte)

var bar1 = new function() { 
    this.value = '#1'; 
} 
var bar2 = new function() { 
    this.value = '#2'; 
} 

function foo() { 
    alert(this.value); 
} 

foo.call(bar1); // Output: #1 
foo.apply(bar2, []); // Output: #2 
+3

Perché il down vota? .. Solo per curiosità. – Atli

+0

Anch'io sono curioso. c'è qualcosa di sbagliato nella sua spiegazione? – goh

+1

La risposta di @Danben pone l'accento sull'utilizzo della nuova parola chiave, che crea un nuovo oggetto (il modo prototipo javascript). Senza di esso, non viene creato alcun nuovo oggetto e la funzione è "internata" (se posso dirlo) all'oggetto a cui appartiene o all'oggetto della finestra globale se nel browser. –

-1

In tutto ciò JavaScript è oggetto anche le funzioni. Quando si dice this.foo nel codice seguente

function Foo() 
{ 
    this.foo = "bar"; // <- What is "this" here? 
} 

foo diventa variabile membro della Foo oggetto

+0

Potrei avere la funzione MyClass() {function MyMethod() {console.log (this); }} e quella registrazione dovrebbe registrare MyClass, non MyMethod. Si noti che sia MyClass che MyMethod sono funzioni, ma nessuno chiamerebbe il nuovo MyClass.MyMethod() se il design non è stato intenzionalemente inteso così. –

+1

Per espandere l'esempio di Luka: se Foo() non è una funzione membro di qualche oggetto personalizzato, diventa una funzione membro dell'oggetto globale ('window' se eseguita nel browser web) nel qual caso' questo 'rimarrà 'window' e quindi' foo' diventeranno la variabile membro di 'window'. – JustAMartin

20

leggere ciò che Douglas Crockford ha da dire sulla questione, per citare lui da A Survey of the JavaScript Programming Language:

Una funzione è un oggetto. Può contenere membri proprio come altri oggetti. Ciò consente a una funzione di contenere le proprie tabelle di dati. Consente inoltre a un oggetto di agire come una classe, contenente un costruttore e un insieme di metodi correlati.

Una funzione può essere un membro di un oggetto. Quando una funzione è membro di un oggetto, viene chiamata metodo. C'è una variabile speciale, chiamata ciò che è impostata sull'oggetto quando viene chiamato un metodo dell'oggetto.

Ad esempio, nell'espressione foo.bar(), questa variabile è impostata sull'oggetto foo come una sorta di argomento aggiuntivo per la barra delle funzioni. La barra delle funzioni può quindi fare riferimento a questo per accedere all'oggetto di interesse.

In un'espressione più profonda come do.re.mi.fa(), questa variabile è impostata sull'oggetto do.re.mi, non sull'oggetto. In una semplice chiamata di funzione, questo è impostato su Global Object (cioè finestra), che non è molto utile. Il comportamento corretto avrebbe dovuto essere quello di preservare il valore corrente di questo, in particolare quando si chiamano le funzioni interne.

Anche 'questo' può cambiare a seconda di come viene richiamata la funzione, continuate a leggere e apply functioncall function.

mi consiglia di trascorrere del tempo sotto forma di apprendimento uno dei più grandi menti di JavaScript nelle sue presentazioni (gratuito), collegati a here.

+0

+1 per il collegamento di presentazione – Xinus

6

In JavaScript, la convenzione (e questa è solo una convenzione) è che qualsiasi funzione che inizia con una lettera maiuscola deve essere utilizzata come costruttore.Quindi, si potrebbe chiamare

var foo = new Foo() e this fare riferimento all'oggetto appena creato che sta per essere referenziato da foo.

Ovviamente, non c'è nulla che ti impedisca di chiamare Foo() da solo, nel qual caso this farebbe quindi riferimento all'oggetto da cui è stata chiamata la funzione. Per evitare confusione, non è raccomandato.

+1

È fantastico che si chiarisca l'utilizzo della nuova parola chiave, poiché quasi nessun utente occasionale ha familiarità con il funzionamento degli oggetti basati su prototipi javascript e genera troppa confusione. –

Problemi correlati