2012-11-16 9 views
5

ho provato a guardare nella ES6 bozza me stesso, ma non sono sicuro dove guardare:`this` di portata globale nel ECMAScript 6

Qualcuno può dirmi se this in ES6 si riferisce necessariamente al globale oggetto? Inoltre, questo oggetto avrà gli stessi membri dell'ambito globale?

Se potessi rispondere per ES5 sarebbe utile anche.

So che this in ambito globale fa riferimento all'oggetto globale nel browser e nella maggior parte degli altri ambienti ES, come Nodo. Voglio solo sapere se questo è il comportamento definito dalle specifiche o se questo è un comportamento esteso che gli implementatori hanno aggiunto (e se questo comportamento continuerà nelle implementazioni ES6). Inoltre, l'oggetto globale è sempre la stessa cosa dell'ambito globale? O ci sono distinzioni?


Update - Perché voglio sapere: Sto fondamentalmente cercando di capire come ottenere l'oggetto globale affidabile in ES5 & 6. Non posso contare su window perché è specifico per il browser, né posso contare su global perché è specifico per ambienti come Node. So che lo this nel nodo può riferirsi allo module nell'ambito del modulo, ma penso che si riferisca ancora allo global nell'ambito globale. Voglio un modo cross-environment ES5 & 6 per ottenere l'oggetto globale (se possibile). Sembra che in tutti gli ambienti che conosco di this in ambito globale lo faccia, ma voglio sapere se fa parte delle specifiche attuali (e quindi affidabile in qualsiasi ambiente con cui non ho familiarità).

Ho anche bisogno di sapere se l'ambito globale e l'oggetto globale sono la stessa cosa dalle specifiche. In altre parole, tutte le variabili nell'ambito globale avranno lo stesso valore di globalobject.variable_name?


Update 2 - Quello che sto cercando di fare:

ho sviluppato una certa ES6 shims for ES5 environments. Voglio sapere il modo migliore per (1) controllare se esistono già i built-in ES6 in modo che possano essere usati quando possibile invece dei miei shim, e (2) aggiungere i miei shim allo scope globale se il built-in ins non esistono già.

Attualmente sto seguendo questo schema:

(function() { 

    // Indirect eval to run in global scope. 
    // (We get whatever "this" is in global scope, hoping that it's the global object... 
    // Whether this line does what I want it to is the crux of my question.) 
    var global = (0, eval)('this'); 

    // If Symbol does not already exist in global scope, 
    if (!global.Symbol) 

     // Then add Symbol to global scope. 
     global.Symbol = (function() { 

      // ... 
      // Return my Symbol shim 

     })(); 

})(); 

Ci sono alcune altre possibilità per (1), ma alla fine della giornata ho bisogno di un modo per aggiungere qualcosa alla portata globale senza utilizzare var in ambito globale (perché questo sovrascriverebbe i built-in prima che io possa controllarli, a causa del sollevamento di var [almeno nel caso naif, forse potrei indirizzare anche l'istruzione eval a var?]). Voglio che il mio codice sia in grado di funzionare in modalità rigorosa, in modo tale da aggravare il problema.

Ho scoperto che, tramite la specifica ES5, eval indiretto esegue il codice in ambito globale. Quindi sono almeno in grado di farlo. Le mie domande sono se ottengo this in ambito globale, (1) Verificando le proprietà di quell'oggetto fammi sapere se esiste già un built-in nell'ambito globale? e (2) L'aggiunta di proprietà a quell'oggetto mi consentirà di aggiungere variabili all'ambito globale?

+3

Dovrebbe funzionare come le precedenti specifiche ES come "questo" non è specifico per ES6. Il significato di "questo" dipende da dove viene usato e non è sempre l'oggetto globale. – Jay

+0

Capito; è per questo che ho chiesto "in ambito globale", dove nei browser "questo" è lo stesso di "finestra", che è anche l'oggetto globale. Non so, tuttavia, se questo è specificato in ES o se è solo un'estensione del browser per la lingua. –

+1

Finché non sei in qualcosa come SES, il trucco di valutazione indiretto funzionerà in modo affidabile. Una volta che hai l'oggetto globale puoi assegnarlo e controllare le proprietà e questo farà ciò che vuoi. In es6, al di là di ciò che Andreas ha detto su let, const, ecc. C'è anche il problema dei moduli che hanno il loro globale privato che ha l'oggetto globale principale come un ambito esterno, quindi è impossibile accedere o modificare l'esterno globale a meno di un riferimento diretto viene fornito (come node.js che definisce automaticamente "globale", per esempio, ti darebbe un riferimento a quello globale esterno). –

risposta

2

Sì, this in ambito globale continuerà a fare riferimento all'oggetto globale in ES6. (In generale, ES6 dovrebbe essere completamente retrocompatibile, vale a dire qualsiasi codice garantito per funzionare in ES5 dovrebbe funzionare anche in ES6).

La nozione di "ambito globale", tuttavia, non sarà più identica all'oggetto globale in ES6. Introduce nuovi moduli di dichiarazione che sono in ambito lessicale (let, const, class, module e alcuni altri). La conclusione all'ultimo incontro è stata che nessuno di questi apparirà come proprietà dell'oggetto globale. C'è una varietà di ragioni tecniche e metodologiche per questo, ma la linea di fondo è che è meglio evitare di utilizzare l'oggetto globale direttamente del tutto (questo è sempre stato vero, ma lo è ancora di più in ES6).

Esiste qualcosa per cui è necessario l'oggetto globale?

+0

Hey Andreas, grazie per aver offerto la tua esperienza! Ho risposto alla tua domanda sul motivo per cui desidero l'oggetto globale nell' ** Update 2 ** del mio post originale. Potresti dare un'occhiata e vedere se il pattern che sto seguendo è buono? Grazie! –

0

Principalmente sì.

Passando this in qualsiasi non-oggetto (o non-set this) faranno riferimento all'oggetto globale:

(function(global){ /* do stuff! */ }(this)); 

Questo comportamento è destinato a restare a ES6 (per problemi di compatibilità comprensibili). Ed è così che la maggior parte dei plugin multipiattaforma (Browser/Node) che conosco stanno accedendo all'oggetto globale. Ad esempio: https://github.com/documentcloud/underscore/blob/master/underscore.js#L12

Sebbene sia vero che il plug-in sul server acceda solo a this come module (che viene esportato). Ma è quello che vuoi nel nodo. Lo spazio globale non viene ripulito mai (tranne se fatto manualmente o riavviato dal server). Quindi è condiviso tra tutte le connessioni client; assegnare qualcosa allo spazio globale non è davvero una buona idea.


L'unica differenza notevole nel modo in cui this viene gestita tra "versione" JavaScript è in strict mode, dove si genera un errore è che se null o undefined viene passato call o apply o bind (nella posizione del this value). In modalità non rigida, this è stato forzato all'oggetto globale.

"use strict"; 
foo.apply(null); // Throw error 

Spero che questo aiuto!

+2

Potrebbe essere stato poco chiaro nel fraseggio, ma 'foo.apply (null);' non genera un errore in modalità rigorosa. 'function foo() {this.doSomething(); } 'genera un errore in modalità strict se non c'è' this' (ad esempio se 'this' è' null' o 'undefined').Potrebbe essere quello che intendevi dire, ma potresti volerlo scrivere più chiaramente per i posteri. –

Problemi correlati