Domanda

Qual è il modo consigliato per ottenere una maniglia per l' oggetto globale in ES5 modalità rigorosa in un ambiente host sconosciuto?

ECMAScript non fornisce un modo integrato per fare riferimento all'oggetto globale di cui sono a conoscenza.Se lo fa, questa è la risposta che sto cercando.

In un ambiente conosciuto, l'oggetto globale di solito ha una proprietà autoreferenziale.Poiché l'oggetto globale è il VO per l'ambito globale, le proprietà dell'oggetto globale sono variabili globali, quindi possiamo usarle per ottenere un handle all'oggetto globale da qualsiasi luogo:

  • In un browser web, possiamo usare window o self.

  • Nel nodo.js, possiamo usare global.

Tuttavia, questo non è necessariamente il caso in tutti gli ambienti host.Per quanto ne so, Windows Script Host non fornisce alcun modo per accedere all'oggetto globale.Il modo consigliato per ottenere l'oggetto globale in WSH sembra essere quello di utilizzare this parola chiave in un contesto in cui non si risolve in un oggetto.Biru:

var GLOBAL = (function(){return this}());

Questa tecnica funzionerà per qualsiasi ambiente host, ma non in modalità rigorosa, perché un this non fa riferimento all'oggetto globale in modalità rigorosa:

Se questo viene valutato all'interno del codice della modalità strict, il valore this non viene forzato a un oggetto. A questo valore di null o undefined non viene convertito nell'oggetto globale e i valori primitivi non vengono convertiti in oggetti wrapper.Il valore this passato tramite una chiamata di funzione(comprese le chiamate effettuate utilizzando la funzione.prototipo.applicare e funzionare.prototipo.call) non forzare il passato questo valore a un oggetto (10.4.3, 11.1.1, 15.3.4.3, 15.3.4.4).

Come previsto, il seguente codice risulta in undefined:

(function(){
    "use strict";
    var GLOBAL = (function(){return this}());
    console.log(GLOBAL);
}());

Quindi, qual è il modo corretto per ottieni una maniglia per l'oggetto globale in qualsiasi ambiente, indipendentemente dalla modalità rigorosa?

A proposito, il mio approccio attuale è quello di annusare le variabili globali che fanno riferimento all'oggetto globale in questo modo:

var self, window, global = global || window || self;

...e poi basta usare global.Penso che questa sia una cattiva soluzione per una serie di motivi, molti dei quali sono abbastanza ovvi, e non affronta il problema WSH.

È stato utile?

Soluzione

In ES5, è possibile ottenere un riferimento all'oggetto globale dall'interno della modalità rigorosa tramite chiamata eval indiretta:

"use strict";
var global = (1,eval)('this');

Dai un'occhiata a il mio articolo;in particolare a questo sezione sulla modalità rigorosa.

Altri suggerimenti

In codice globale, il thisBinding è impostato sull'oggetto globale indipendentemente dalla modalità rigorosa.Ciò significa che puoi passarlo da lì nel tuo modulo IEFE:

// "use strict"; or not
(function(global) {
    "use strict";
    …
    console.log(global);
    …
}(this));

In modalità rigorosa, il modo per ottenere un riferimento all'oggetto globale è assegnare una variabile nell'oggetto globale che fa riferimento a se stesso.

Cioè this indica l'oggetto globale quando nel contesto globale, quindi la soluzione è semplicemente:

"use strict";
var global = global || this;
(function() { global.hello = "world"; })();
console.log(hello); // Outputs 'world' as expected

Questo fare significa che devi inquinare lo spazio dei nomi globale con un riferimento a se stesso, ma come dici tu, dovrebbe già esserci stato.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top