Como declarar uma variável global em um arquivo .js

86

Preciso de algumas variáveis ​​globais que preciso em todos os .jsarquivos.

Por exemplo, considere os seguintes 4 arquivos:

  1. global.js
  2. js1.js
  3. js2.js
  4. js3.js

Existe uma maneira de declarar 3 variáveis ​​globais global.jse acessá-las em qualquer um dos outros 3 .jsarquivos, considerando que carrego todos os 4 arquivos acima em um documento HTML?

Alguém pode me dizer se isso é possível ou existe uma solução alternativa para conseguir isso?

kp11
fonte

Respostas:

94

Basta definir suas variáveis ​​em global.js fora do escopo de uma função:

// global.js
var global1 = "I'm a global!";
var global2 = "So am I!";

// other js-file
function testGlobal () {
    alert(global1);
}

Para garantir que isso funcione, você deve incluir / vincular a global.js antes de tentar acessar qualquer variável definida nesse arquivo:

<html>
    <head>
        <!-- Include global.js first -->
        <script src="/YOUR_PATH/global.js" type="text/javascript"></script>
        <!-- Now we can reference variables, objects, functions etc. 
             defined in global.js -->
        <script src="/YOUR_PATH/otherJsFile.js" type="text/javascript"></script>
    </head>
    [...]
</html>

Você pode, é claro, criar um link nas tags de script antes da tag de fechamento <body>, se não quiser que o carregamento de arquivos js interrompa o carregamento da página inicial.

PatrikAkerstrand
fonte
4
Embora essa resposta esteja correta, eu recomendo que você use o escopo da variável Javascript do Google para obter um melhor entendimento e, possivelmente, evitar fazer as coisas dessa maneira exata.
aleemb
1
Acordado. Sempre tento definir o escopo de todas as funções e variáveis ​​em um "namespace" comum para evitar confusão e conflitos. Normalmente, eu o nomeio como uma abreviação do projeto ou empresa.
PatrikAkerstrand
Votar negativamente nesta resposta e em outras semelhantes porque pressupõe que a variável global será criada em um escopo global e também requer que a primeira menção da variável esteja no escopo global antes de todas as outras menções.
Andrew
1
@Andrew Esta resposta foi escrita há oito anos. Para todos os efeitos, estava correto naquela época. Se você quiser realmente fazer uma contribuição, pode sugerir uma edição.
PatrikAkerstrand
@PatrikAkerstrand O namoro na verdade não faz diferença. As outras respostas que usam um objeto global são suficientes; Eu expliquei por que isso não é.
Andrew
89

A abordagem recomendada é:

window.greeting = "Hello World!"

Você pode acessá-lo em qualquer função:

function foo() {

   alert(greeting); // Hello World!
   alert(window["greeting"]); // Hello World!
   alert(window.greeting); // Hello World! (recommended)

}

Essa abordagem é preferida por dois motivos.

  1. A intenção é explícita. O uso da varpalavra - chave pode facilmente levar à declaração de globais varsque deveriam ser locais ou vice-versa. Esse tipo de escopo de variável é um ponto de confusão para muitos desenvolvedores de Javascript. Portanto, como regra geral, asseguro-me de que todas as declarações de variáveis ​​sejam precedidas da palavra-chave varou do prefixo window.

  2. Você padroniza esta sintaxe para ler as variáveis ​​dessa maneira também, o que significa que um escopo local varnão supera o global varou vice-versa. Por exemplo, o que acontece aqui é ambíguo:

 

 greeting = "Aloha";

 function foo() {
     greeting = "Hello"; // overrides global!
 }

 function bar(greeting) {
   alert(greeting);
 }

 foo();
 bar("Howdy"); // does it alert "Hello" or "Howdy" ?

No entanto, isso é muito mais limpo e menos sujeito a erros (você realmente não precisa se lembrar de todas as regras de escopo de variáveis):

 function foo() {
     window.greeting = "Hello";
 }

 function bar(greeting) {
   alert(greeting);
 }

 foo();
 bar("Howdy"); // alerts "Howdy"
Aleemb
fonte
Anexar variáveis ​​à janela deve funcionar em todos os navegadores (e também é a abordagem que utilizo, +1!).
Dandy
1
@Dan, se você declarar "var testvar = 'hello';" fora de uma função, ele é adicionado automaticamente ao objeto janela e você pode acessá-lo com "window.testvar".
zkent
1
@zkent, isso mesmo, mas usar o objeto Window é ainda melhor porque você pode querer transformar seu código em algo como café mais tarde.
Nami WANG
É melhor usar a janela em vez do prefixo do documento?
Andrew
7

Tentaste?

Se você fizer:

var HI = 'Hello World';

Em global.js. E então faça:

alert(HI);

No js1.jsele irá alertá-lo bem. Você apenas tem que incluir global.jsantes do resto no documento HTML.

O único problema é que você deve declará-lo no escopo da janela (não dentro de nenhuma função).

Você poderia simplesmente anular a varpeça e criá-la dessa forma, mas não é uma boa prática.

Paolo Bergantino
fonte
7

Conforme mencionado acima, há problemas com o uso do escopo superior em seu arquivo de script. Aqui está outro problema: O arquivo de script pode ser executado a partir de um contexto que não é o contexto global em algum ambiente de tempo de execução.

Foi proposto atribuir o global windowdiretamente. Mas isso também depende do tempo de execução e não funciona no Node etc. Isso mostra que o gerenciamento de variável global portátil precisa de alguma consideração cuidadosa e esforço extra. Talvez eles consertem em futuras versões do ECMS!

Por enquanto, eu recomendaria algo assim para oferecer suporte ao gerenciamento global adequado para todos os ambientes de tempo de execução:

/**
 * Exports the given object into the global context.
 */
var exportGlobal = function(name, object) {
    if (typeof(global) !== "undefined")  {
        // Node.js
        global[name] = object;
    }
    else if (typeof(window) !== "undefined") {
        // JS with GUI (usually browser)
        window[name] = object;
    }
    else {
        throw new Error("Unkown run-time environment. Currently only browsers and Node.js are supported.");
    }
};


// export exportGlobal itself
exportGlobal("exportGlobal", exportGlobal);

// create a new global namespace
exportGlobal("someothernamespace", {});

É um pouco mais de digitação, mas torna o gerenciamento de variável global à prova de futuro.

Aviso de isenção de responsabilidade: Parte dessa ideia me ocorreu ao examinar as versões anteriores do stacktrace.js .

Acho que também se pode usar o Webpack ou outras ferramentas para obter uma detecção mais confiável e menos invasiva do ambiente de tempo de execução.

Domi
fonte
2
GLOBALagora está obsoleto e globaldeve ser usado em seu lugar.
Thomas,
2

Sim, você pode acessá-los. Você deve declará-los em 'espaço público' (fora de quaisquer funções) como:

var globalvar1 = 'value';

Você pode acessá-los mais tarde, também em outros arquivos.

Ropstah
fonte