88 votes

Qu'est-ce que cela signifie que l'espace de noms global serait pollué ?

Qu'est-ce que cela signifie que l'espace de noms global serait pollué ?

Je ne comprends pas vraiment ce que signifie la pollution de l'espace de noms global.

120voto

Travis J Points 28588

Note rapide sur la collecte d'ordures

Au fur et à mesure que les variables perdent de leur portée, elles sont éligibles pour la collecte des déchets. Si elles ont une portée globale, elles ne pourront être collectées que lorsque l'espace de nom global perdra sa portée.

Voici un exemple :

var arra = [];
for (var i = 0; i < 2003000; i++) {
 arra.push(i * i + i);
}

Ajouter ceci à votre espace de noms global (du moins pour moi) devrait ajouter 10 000 kb d'utilisation de la mémoire (win7 firefox) qui ne seront pas collectés. D'autres navigateurs peuvent gérer cela différemment.

Alors qu'avoir ce même code dans une portée qui sort de la portée comme ceci :

(function(){
 var arra = [];
 for (var i = 0; i < 2003000; i++) {
  arra.push(i * i + i);
 }
})();

Permettra arra pour perdre sa portée après l'exécution de la fermeture et être éligible à la collecte des déchets.

Le Global Namespace est votre ami

Malgré les nombreuses critiques à l'encontre de l'utilisation de l'espace de nom global, celui-ci est votre ami. Et comme un bon ami, vous ne devez pas abuser de votre relation.

Soyez doux

N'abusez pas (on dit généralement "pollue") de l'espace de noms global. Et ce que je veux dire par ne pas abuser de l'espace de noms global, c'est qu'il ne faut pas créer plusieurs variables globales. Voici un exemple mauvais exemple d'utilisation de l'espace de noms global.

var x1 = 5;
var x2 = 20;
var y1 = 3
var y2 = 16;

var rise = y2 - y1;
var run = x2 - x1;

var slope = rise / run;

var risesquared = rise * rise;
var runsquared = run * run;

var distancesquared = risesquared + runsquared;

var distance = Math.sqrt(dinstancesquared);

Cela va créer 11 variables globales qui pourraient éventuellement être écrasées ou mal interprétées quelque part.

Soyez ingénieux

Une approche plus ingénieuse, qui ne pollue pas l'espace de noms global, consisterait à envelopper tout cela dans le modèle de module et à n'utiliser qu'une seule variable globale tout en exposant plusieurs variables.

Voici un exemple : (Veuillez noter qu'il s'agit d'un exemple simple et qu'il n'y a pas de gestion des erreurs).

//Calculate is the only exposed global variable
var Calculate = function () {
 //all defintions in this closure are local, and will not be exposed to the global namespace
 var Coordinates = [];//array for coordinates
 var Coordinate = function (xcoord, ycoord) {//definition for type Coordinate
   this.x = xcoord;//assign values similar to a constructor
   this.y = ycoord;
  };

  return {//these methods will be exposed through the Calculate object
   AddCoordinate: function (x, y) {
   Coordinates.push(new Coordinate(x, y));//Add a new coordinate
  },

  Slope: function () {//Calculates slope and returns the value
   var c1 = Coordinates[0];
   var c2 = Coordinates[1];
   return c2.y - c1.y / c2.x - c1.x;//calculates rise over run and returns result
  },

  Distance: function () {
   //even with an excessive amount of variables declared, these are all still local
   var c1 = Coordinates[0];
   var c2 = Coordinates[1];

   var rise = c2.y - c1.y;
   var run = c2.x - c1.x;

   var risesquared = rise * rise;
   var runsquared = run * run;

   var distancesquared = risesquared + runsquared;

   var distance = Math.sqrt(distancesquared);

   return distance;
  }
 };
};

//this is a "self executing closure" and is used because these variables will be
//scoped to the function, and will not be available globally nor will they collide
//with any variable names in the global namespace
(function () {
 var calc = Calculate();
 calc.AddCoordinate(5, 20);
 calc.AddCoordinate(3, 16);
 console.log(calc.Slope());
 console.log(calc.Distance());
})();

20voto

James Allardice Points 81162

En JavaScript, les déclarations en dehors d'une fonction sont dans la portée globale. Considérez ce petit exemple :

var x = 10;
function example() {
    console.log(x);
}
example(); //Will print 10

Dans l'exemple ci-dessus, x est déclaré dans la portée globale. Toute portée enfant, telle que celle créée par la balise example héritent effectivement des éléments déclarés dans les portées parent (dans ce cas, il s'agit uniquement de la portée globale).

Toute portée enfant qui redéclare une variable déclarée dans la portée globale fera l'ombre de la variable globale, ce qui peut provoquer des bogues indésirables et difficiles à repérer :

var x = 10;
function example() {
    var x = 20;
    console.log(x); //Prints 20
}
example();
console.log(x); //Prints 10

Les variables globales ne sont généralement pas recommandées en raison des problèmes qu'elles peuvent causer. Si nous n'avions pas utilisé la variable var à l'intérieur du example nous aurions accidentellement écrasé la valeur de la fonction x dans la portée globale :

var x = 10;
function example() {
    x = 20; //Oops, no var statement
    console.log(x); //Prints 20
}
example();
console.log(x); //Prints 20... oh dear

Si vous voulez en savoir plus et bien comprendre, je vous suggère de consulter le site web de la Commission européenne. Spécification ECMAScript . Ce n'est peut-être pas la lecture la plus passionnante, mais elle sera d'une grande utilité.

8voto

Sergio Tulentsev Points 82783

Lorsque vous déclarez des variables globales, des fonctions, etc., elles sont placées dans l'espace de noms global. En dehors des problèmes de performance/mémoire (qui peuvent survenir), vous risquez de vous heurter à de fâcheux conflits de noms, lorsque vous redéfinissez une variable importante ou que vous n'utilisez pas la valeur que vous pensez utiliser.

Il faut éviter de définir des choses dans l'espace de noms global.

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