web-dev-qa-db-fra.com

Dois-je utiliser window.variable ou var?

Nous avons beaucoup de code JS de configuration qui définit les panneaux, les boutons, etc. qui seront utilisés dans de nombreux autres fichiers JS.

En règle générale, nous faisons quelque chose comme:

grid.js

var myGrid = .....

combos.js

var myCombo = .....

Ensuite, dans notre code d'application, nous:

application.js

function blah() {
    myGrid.someMethod()
}

someother.js

function foo() {
    myCombo.someMethod();
    myGrid.someMethod();
}

Donc, devrions-nous utiliser le var myGrid ou mieux vaut utiliser window.myGrid

Quelle est la différence?

55
cbmeeks

Je suggère de créer une variable d'espace de noms var App = {};

App.myGrid = ...

De cette façon, vous pouvez limiter la pollution de l'espace de noms global.

EDIT: Concernant le nombre de problèmes de variables - 2 solutions possibles viennent à l'esprit:

  1. Vous pouvez en outre les nommer par type (grilles, boutons, etc.) ou par relation (ClientInfoSection, AddressSection, etc.)
  2. Vous encapsulez vos méthodes dans des objets qui sont instanciés avec les composants que vous avez

ex: vous avez

function foo() {
    myCombo.someMethod();
    myGrid.someMethod();
}

devient:

var Foo = function(combo, grid) {
    var myCombo = combo;//will be a private property
    this.myGrid = grid;//will be a public property
    this.foo = function() {//public method
        myCombo.someMethod();
        myGrid.someMethod();
    }
}
App.myFoo = new Foo(someCombo, someGrid);
App.myFoo.foo();

de cette façon, vous limitez la quantité de petits objets et n'exposez que ce dont vous avez besoin (à savoir la fonction foo)

PS: si vous avez besoin d'exposer les composants internes, ajoutez-les à l'intérieur de la fonction constructeur

40
Liviu T.

Une différence de fonctionnalité potentiellement importante est que window.myGrid peut être deleted et var myGrid ne peux pas.

var test1 = 'value';
window.test2 = 'value';


console.log( delete window.test1 ); // false ( was not deleted )
console.log( delete window.test2 ); // true  ( was deleted )


console.log( test1 );  // 'value'         ( still accessible )
console.log( test2 );  // ReferenceError  ( no longer exists )
58
user113716

Une belle utilisation de window.variable est que vous pouvez le vérifier sans avoir d'erreur javascript. Par exemple, si vous avez:

if (myVar) {
    //do work
}

et myVar n'est défini nulle part sur la page, vous obtiendrez une erreur javascript. Toutefois:

if (window.myVar) {
    //do work
}

ne donne aucune erreur et fonctionne comme on pourrait s'y attendre.

var myVar = 'test' et window.myVar = 'test' sont à peu près équivalents.

En plus de cela, comme d'autres l'ont dit, vous devez descendre d'un objet global pour éviter de polluer l'espace de noms global.

11
aepheus

À l'échelle mondiale, les deux sont en fait des fonctionnalités équivalentes. Dans la portée de la fonction, var est certainement préférable lorsque le comportement des fermetures est souhaité.

Je voudrais simplement utiliser var tout le temps: premièrement, il est cohérent avec le comportement généralement préféré dans les fermetures (il est donc plus facile de déplacer votre code dans une fermeture si vous décidez de le faire plus tard), et deuxièmement, il me semble plus sémantique de dire que je crée une variable que d'attacher une propriété de la fenêtre. Mais c'est surtout du style à ce stade.

8
Jeremy Roman

La réponse générale à la question serait d'utiliser var.

Plus précisément, mettez toujours votre code dans une expression de fonction immédiatement invoquée (IIFE) :

(function(){
  var foo,
      bar;
  ...code...
})();

Cela empêche les variables comme foo et bar de polluer l'espace de noms global. Ensuite, lorsque vous voulez explicitement que une variable soit sur l'objet global (généralement window), vous pouvez écrire:

window.foo = foo;

JavaScript a une portée fonctionnelle, et il est vraiment bon d'en tirer pleinement parti. Vous ne voudriez pas que votre application se casse juste parce qu'un autre programmeur a fait quelque chose de stupide, comme écraser la poignée de votre minuterie.

6
zzzzBov

En plus d'autres réponses, il convient de noter que si vous n'utilisez pas var à l'intérieur d'une fonction lors de la déclaration d'une variable, elle fuites dans la portée globale en faisant automatiquement une propriété de window objet (ou portée globale).

3
Mrchief

Pour développer ce que Liviu a dit, utilisez:

App = (function() {
    var exports = {};
    /* code goes here, attach to exports to create Public API */
    return exports; 
})();

En faisant cela, vous pouvez masquer une partie de votre code spécifique à l'implémentation, que vous ne voudrez peut-être pas voir en utilisant l'intérieur de var. Cependant, vous pouvez accéder à tout ce qui est attaché à l'objet exports.

1
Justin Long