299 votes

Variables globales JavaScript

y a-t-il une différence entre la déclaration d’une variable

et cette façon

ou

dans le contexte global ?

569voto

T.J. Crowder Points 285826

Oui, il y a deux différences, même si dans la pratique ils ne sont pas généralement les plus grands.

Vos trois déclarations expliqué

var a=0;

...crée une variable sur la variable de l'objet pour le mondial du contexte d'exécution, qui est l'objet global, qui sur les navigateurs est l'alias window (et c'est un DOM objet de la fenêtre plutôt que de simplement un objet générique, comme il le serait sur la non-navigateur implémentations). Le symbole window , lui, est en fait une propriété de la global (de la fenêtre) de l'objet qu'il utilise pour pointer vers lui-même.

Le résultat de tout ce qui est: Il crée une propriété sur window que vous ne pouvez pas supprimer. Il est également défini avant la première ligne de code s'exécute (voir "Quand var passe" ci-dessous).

Notez que sur IE8 et plus tôt, le bien créé sur window n'est pas énumérable (ne pas s'afficher en for..in des déclarations). Dans IE9, Chrome, Firefox et Opera, c'est énumérable.


a=0;

...crée une propriété sur l' window objet implicitement. Comme c'est une propriété classique, vous pouvez le supprimer. Je vous recommande de ne pas le faire, il peut être difficile de savoir à toute personne la lecture de votre code plus tard.

Et il est intéressant de noter, à nouveau sur IE8 et plus tôt, le bien créé non énumérable (ne pas s'afficher en for..in des déclarations). C'est étrange, compte tenu notamment de la ci-dessous.


window.a=0;

...crée une propriété sur l' window objet explicitement. Comme c'est une propriété classique, vous pouvez le supprimer.

Cette propriété est énumérable, sur IE8 et plus haut, et sur tous les autres navigateurs que j'ai essayé.

Un quatrième moyen

Il y a encore une autre façon de le faire, d'ailleurs:

this.a=0;

...parce que dans le contexte d'exécution global, this références de l'objet global. Donc, this.a=0; est identique à window.a=0; (sauf peut être un teensy, teensy peu plus vite parce qu' this n'a pas à être recherché; probablement impossible à mesurer dans tout scénario réel).

Puisque c'est le même que window.a=0;, c'est sans surprise que cela crée une énumération des biens (même sur IE8 et ci-dessous).


La suppression de propriétés

Ce que je veux dire par "suppression"? Exactement que: la Suppression de la propriété (entièrement) par l'intermédiaire de l' delete mot-clé:

window.a = 0;
display("'a' in window? " + ('a' in window)); // displays "true"
delete window.a;
display("'a' in window? " + ('a' in window)); // displays "false"

delete supprime complètement une propriété d'un objet. Vous ne pouvez pas le faire avec les propriétés ajoutées à l' window indirectement par l'intermédiaire d' var, delete est soit ignorée en mode silencieux ou lève une exception (selon le JavaScript de la mise en œuvre et si vous êtes en mode strict).

Avertissement: Internet Explorer ne vous laisseront pas de supprimer les propriétés de l' window objet, même quand vous devriez être autorisé à le faire. Pire, elle lève une exception lorsque vous essayez (essayez cette expérience dans IE et les autres navigateurs). Donc, lors de la suppression de l' window objet, vous avez à être sur la défensive:

try {
    delete window.prop;
}
catch (e) {
    window.prop = undefined;
}

Qui tente de supprimer la propriété, et si une exception est levée, il ne de la prochaine meilleure chose et définit la propriété d' undefined.

Cette seule s'applique à l' window objet, et que (pour autant que je sache) à IE. Les autres navigateurs sont très bien avec la suppression d' window propriétés, sous réserve des règles ci-dessus.


Lors de l' var arrive

Il y a une autre différence entre l' var version et les autres. Elle correspond au moment où le symbole est créé. Les symboles définis par l' var déclaration sont créés avant toute étape-par-étape de code dans le contexte d'exécution est exécuté, et si la propriété existe bien avant l' var déclaration.

Cela peut être source de confusion, donc, nous allons jeter un coup d'oeil:

display("foo in window? " + ('foo' in window)); // displays "true"
display("window.foo = " + window.foo);          // displays "undefined"
display("bar in window? " + ('bar' in window)); // displays "false"
display("window.bar = " + window.bar);          // displays "undefined"
var foo = "f";
bar = "b";
display("foo in window? " + ('foo' in window)); // displays "true"
display("window.foo = " + window.foo);          // displays "f"
display("bar in window? " + ('bar' in window)); // displays "true"
display("window.bar = " + window.bar);          // displays "b"

Live exemple

Comme vous pouvez le voir, le symbole foo est défini avant la première ligne, mais le symbole bar ne l'est pas. Où l' var foo = "f"; déclaration est, il y a vraiment deux choses: la définition du symbole, qui se produit avant la première ligne de code est exécuté; et de faire une mission à ce symbole, ce qui arrive lorsque la ligne est dans l'étape-par-étape du flux. (Voir les Pauvres incompris var)


Hors-sujet: Évitez d'encombrer window

L' window objet devient très, très encombré avec des propriétés. Chaque fois que possible, vous recommandons fortement de ne pas ajouter à la pagaille. Au lieu de cela, enveloppez vos symboles dans un petit paquet et l'exportation à plus d'un symbole à l' window objet. (J'ai souvent de ne pas exporter tous les symboles à l' window objet). Vous pouvez utiliser une fonction à contenir l'ensemble de votre code afin de contenir les symboles, et que la fonction peut être anonyme si vous le souhaitez:

(function() {
    var a = 0; // `a` is NOT a property of `window` now

    function foo() {
        alert(a);   // Alerts "0", because `foo` can access `a`
    }
})();

Dans cet exemple, nous définissons une fonction et de l'exécuter tout de suite ( () à la fin).

Une fonction utilisée de cette manière est souvent appelée la portée de la fonction. Les fonctions définies dans la détermination de la portée de la fonction peuvent accéder à des variables définies dans la détermination de la portée de la fonction, parce qu'ils sont des fermetures sur les données (voir: les Fermetures ne sont pas compliquées).

40voto

Umair Points 1194

Le garder simple :

Le code ci-dessus donne une variable de portée globale

Copiez le code suivant donnera une variable destinée à être utilisée dans la portée actuelle et sous elle

C’est généralement identique à la variable globale.

10voto

Cody Points 1198
<pre><code></code><p>Y a-t-il un objet global qui toutes variables sont accrochés au large de par défaut ? par exemple : « déclaration de globals.noVar »</p></pre>

5voto

Raynos Points 82706

Dans une portée mondiale, il n'y a pas de différence sémantique.

Mais vous devriez vraiment éviter a=0 depuis votre réglage d'une valeur à une variable non déclarée.

Aussi l'utilisation de fermetures afin d'éviter d'éditer une portée mondiale, à tous les

(function() {
   // do stuff locally

   // Hoist something to global scope
   window.someGlobal = someLocal
}());

Toujours utiliser les fermetures et les hissent toujours à portée globale lorsqu'il est absolument nécessaire de le modifier. Vous devriez être en utilisant la gestion des événements asynchrones pour la plupart de vos actions de communication de toute façon.

@AvianMoncellor mentionné il y a un bug avec IE var a = foo seulement de déclarer un mondial de la portée de fichier. C'est un problème avec IE, la célèbre cassé interprète. Ce bogue ne sonne familier, alors il est probablement vrai.

Alors restez à l' window.globalName = someLocalpointer

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X