Comment déclarer une variable globale dans un fichier .js

86

J'ai besoin de quelques variables globales dont j'ai besoin dans tous les .jsfichiers.

Par exemple, considérez les 4 fichiers suivants:

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

Existe-t-il un moyen de déclarer 3 variables globales dans global.jset d'y accéder dans l'un des 3 autres .jsfichiers en considérant que je charge les 4 fichiers ci-dessus dans un document HTML?

Quelqu'un peut-il me dire si cela est possible ou y a-t-il une solution pour y parvenir?

kp11
la source

Réponses:

96

Définissez simplement vos variables dans global.js en dehors d'une portée de fonction:

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

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

Pour vous assurer que cela fonctionne, vous devez inclure / lien vers global.js avant d'essayer d'accéder aux variables définies dans ce fichier:

<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>

Vous pouvez bien sûr créer un lien dans les balises de script juste avant la balise de fermeture <body> si vous ne voulez pas que le chargement des fichiers js interrompe le chargement initial de la page.

PatrikAkerstrand
la source
4
Bien que cette réponse soit correcte, je vous recommanderais de définir la portée des variables JavaScript de Google pour mieux comprendre et éventuellement éviter de faire les choses de cette manière exacte.
aleemb
1
D'accord. J'essaie toujours de définir toutes les fonctions et variables dans un «espace de noms» commun pour éviter l'encombrement et les conflits. Habituellement, je le nomme comme une abréviation du projet ou de l'entreprise.
PatrikAkerstrand
Le vote défavorable de cette réponse et des autres l'aime car il suppose que la variable globale va être créée dans une portée globale, et il nécessite également que la première mention de la variable soit dans la portée globale avant toutes les autres mentions.
Andrew
1
@Andrew Cette réponse a été écrite il y a huit ans. À toutes fins utiles, c'était correct à l'époque. Si vous souhaitez réellement apporter une contribution, vous voudrez peut-être suggérer une modification à la place?
PatrikAkerstrand
@PatrikAkerstrand La datation ne fait aucune différence. Les autres réponses qui utilisent un objet global sont suffisantes; J'ai expliqué pourquoi ce n'est pas le cas.
Andrew
89

L'approche recommandée est:

window.greeting = "Hello World!"

Vous pouvez ensuite y accéder dans n'importe quelle fonction:

function foo() {

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

}

Cette approche est préférée pour deux raisons.

  1. L'intention est explicite. L'utilisation du varmot - clé peut facilement conduire à déclarer des globaux varsdestinés à être locaux ou vice versa. Ce type de portée variable est un point de confusion pour de nombreux développeurs Javascript. Donc, en règle générale, je m'assure que toutes les déclarations de variables sont précédées du mot-clé varou du préfixe window.

  2. Vous standardisez également cette syntaxe pour lire les variables de cette manière, ce qui signifie qu'une portée locale varne coupe pas le global varou vice versa. Par exemple, ce qui se passe ici est ambigu:

 

 greeting = "Aloha";

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

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

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

Cependant, c'est beaucoup plus propre et moins sujet aux erreurs (vous n'avez pas vraiment besoin de vous souvenir de toutes les règles de portée des variables):

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

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

 foo();
 bar("Howdy"); // alerts "Howdy"
Aleemb
la source
Attacher des variables à la fenêtre devrait fonctionner sur tous les navigateurs (et c'est aussi l'approche que j'adopte, +1!).
Dandy
1
@Dan, si vous déclarez "var testvar = 'hello';" en dehors d'une fonction, il est automatiquement ajouté à l'objet window et vous pouvez y accéder avec "window.testvar".
zkent
1
@zkent, c'est vrai, mais utiliser l'objet Window est encore mieux car vous voudrez peut-être transformer votre code en qc comme du café plus tard.
Nami WANG
Est-il préférable d'utiliser le préfixe Window plutôt que Document?
Andrew
7

L'as tu essayé?

Si tu fais:

var HI = 'Hello World';

Dans global.js. Et puis faites:

alert(HI);

Dans js1.jscela l'alertera très bien. Il vous suffit d'inclure global.jsavant le reste dans le document HTML.

Le seul problème est que vous devez le déclarer dans la portée de la fenêtre (et non dans aucune fonction).

Vous pouvez simplement supprimer la varpièce et la créer de cette façon, mais ce n'est pas une bonne pratique.

Paolo Bergantino
la source
7

Comme mentionné ci-dessus, il y a des problèmes avec l'utilisation de la portée la plus élevée dans votre fichier de script. Voici un autre problème: le fichier de script peut être exécuté à partir d'un contexte qui n'est pas le contexte global dans un environnement d'exécution.

Il a été proposé d'assigner windowdirectement le global . Mais cela dépend également de l' exécution et ne fonctionne pas dans Node, etc. Cela montre que la gestion des variables globales portables nécessite une attention particulière et des efforts supplémentaires. Peut-être qu'ils le corrigeront dans les futures versions d'ECMS!

Pour l'instant, je recommanderais quelque chose comme celui-ci pour prendre en charge une gestion globale appropriée pour tous les environnements d'exécution:

/**
 * 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", {});

C'est un peu plus typé, mais cela rend votre gestion globale des variables pérenne.

Avis de non-responsabilité: Une partie de cette idée m'est venue en regardant les versions précédentes de stacktrace.js .

Je pense que l'on peut également utiliser Webpack ou d'autres outils pour obtenir une détection plus fiable et moins piratée de l'environnement d'exécution.

Domi
la source
2
GLOBALest désormais obsolète et globaldoit être utilisé à la place.
Thomas
2

Oui, vous pouvez y accéder. Vous devez les déclarer dans `` l'espace public '' (en dehors de toute fonction) comme:

var globalvar1 = 'value';

Vous pourrez y accéder ultérieurement, également dans d'autres fichiers.

Ropstah
la source