2011-11-02 11 views
7

Ok, quindi ho pensato di aver capito questo (nessun gioco di parole previsto), ma apparentemente no.questa parola chiave è oggetto finestra all'interno di una funzione di costruzione

var Constructor = function() { 
    var internalFunction = function() { 
     return this === window; 
    }; 
    this.myMethod = function() { 
     alert(internalFunction()); 
    }; 
}; 
var myObj = new Constructor(); 
myObj.myMethod(); 

Questo avviso true. Perché la funzione interna non può vedere this come oggetto? Invece devo usare alert(internalFunction.call(this)); in myMethod.

Edit: ero alla ricerca di una spiegazione sul motivo per cui this viene assegnato in quel modo, non soluzioni alternative come ad esempio var self = this;, ecc Scusate se non ho fatto chiaro.

+1

Nessuna delle risposte a questa domanda usare 'that'. Mi sento tradito. – hugomg

+0

@missingno: non mi piace "quello". Non è descrittivo. Detto questo, la mia scelta nella mia risposta non è migliore :) –

+0

+1 per gioco non intenzionale – SMC

risposta

6

this non è vincolato finché non viene chiamata la funzione e dipende da come viene chiamata la funzione. Si potrebbe pensare ad esso come a un parametro extra passato implicitamente alla funzione.

In questo caso, il problema è che si sta chiamando internalFunction utilizzando internalFunction(). Il valore this viene impostato chiamando una funzione come metodo (come in foo.bar() o foo["bar"]()) o impostando this esplicitamente tramite call() o apply(). La tua chiamata non sta facendo né così così this ritorna all'oggetto globale.

Il modo più semplice per ottenere ciò che si desidera in questo caso, mantenendo internalFunction privato è quello di memorizzare un riferimento al this all'interno della funzione di costruzione:

var Constructor = function() { 
    var thisObj = this; 

    var internalFunction = function() { 
     return thisObj === window; 
    }; 

    thisObj.myMethod = function() { 
     alert(internalFunction()); 
    }; 
} 
+0

Ah, questo ha senso ... "questo" è assegnato in fase di chiamata, quindi chiamando 'internalFunction()' sto implicitamente chiamando 'window.internalFunction()'. Ben spiegato –

+0

Prenderò l'assegnazione delle funzioni sulla dichiarazione ogni giorno ... – jondavidjohn

+0

@jondavidjohn: Non mi sto occupando di una discussione su questo ed è stato un inutile aggiustamento del codice originale da parte mia, quindi l'ho ripristinato. Grazie per segnalarlo. –

1

E 'un problema di portata provare qualcosa di simile:

var Constructor = function() { 
    var $this = this; 
    var internalFunction = function() { 
     return $this === window; 
    }; 
    this.myMethod = function() { 
     alert(internalFunction()); 
    }; 
}; 
var myObj = new Constructor(); 
myObj.myMethod(); 
3

A causa di regole di visibilità funzionali, this viene riassegnato all'interno di ogni funzione ... Vorrei memorizzare una copia del vostro oggetto come self e utilizzarlo di conseguenza ..

var Constructor = function() { 

    var self = this; 

    var internalFunction = function() { 
     return self === window; 
    }; 
    this.myMethod = function() { 
     alert(internalFunction()); 
    }; 
}; 
var myObj = new Constructor(); 
myObj.myMethod(); 

Dovrebbe darti l'output che ti aspetti.

SideNote

Questa è una pratica abbastanza precaria che javascript ha creato, soprattutto perché se si dimentica la parola chiave new quando si utilizza Constructor, si sarà ottenere this riferendosi al (dio) oggetto window quindi aggiungerai myMethod alla finestra senza preavviso.

2

ci sono cinque modi per chiamare una funzione in JavaScript. Il valore di this dipende da quale si sceglie:

  1. chiamata di funzione Global (ad esempio myFunction()). Non viene fornito alcun valore esplicito per this. Il valore di this sarà l'oggetto predefinito (window in un browser).
  2. Chiamata metodo (ad esempio obj.myFunction()).Il valore di this è l'oggetto su cui è stato richiamato il metodo (obj in questo caso).
  3. Utilizzo del metodo call (ad esempio myFunction.call(obj)). Il valore di this viene fornito esplicitamente (in questo caso obj).
  4. Utilizzo del metodo apply (ad esempio myFunction.apply(obj)). Il valore di this viene fornito esplicitamente (in questo caso obj).
  5. Funzione di costruzione (ad esempio new MyFunction()). Il valore di this è un oggetto appena creato fornito dal runtime.

Ognuno dei cinque è spiegato in dettaglio qui:

Problemi correlati