Qu'est-ce que cela signifie que l'espace de noms global serait pollué?
Je ne comprends pas vraiment ce que signifie l'espace de noms global pollué.
Réponses:
Note rapide sur la collecte des ordures
À mesure que les variables perdent de leur portée, elles seront éligibles pour le garbage collection. S'ils sont étendus globalement, ils ne seront pas éligibles pour la collection tant que l'espace de noms global n'aura pas perdu sa portée.
Voici un exemple:
var arra = [];
for (var i = 0; i < 2003000; i++) {
arra.push(i * i + i);
}
L'ajout de cela à votre espace de noms global (du moins pour moi) devrait ajouter 10 000 Ko d'utilisation de la mémoire (win7 firefox) qui ne seront pas collectés. D'autres navigateurs peuvent gérer cela différemment.
Alors que d'avoir ce même code dans une portée qui sort du champ d'application comme ceci:
(function(){
var arra = [];
for (var i = 0; i < 2003000; i++) {
arra.push(i * i + i);
}
})();
Permettra arrade perdre de la portée après l'exécution de la fermeture et sera éligible pour le ramasse-miettes.
L'espace de noms global est votre ami
Malgré les nombreuses réclamations contre l'utilisation de l'espace de noms global, c'est votre ami. Et comme un bon ami, vous ne devez pas abuser de votre relation.
Sois gentil
N'abusez pas (généralement appelé «polluant») de l'espace de noms global. Et ce que je veux dire par ne pas abuser de l'espace de noms global, c'est - ne pas créer plusieurs variables globales. Voici un 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 que c'est 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());
})();
Calculate.prototype.Slope()hors du périmètre? Il serait très parfait de comprendre un autre concept proche de cette problématique!
En JavaScript, les déclarations en dehors d'une fonction sont dans la portée globale. Prenons ce petit exemple:
var x = 10;
function example() {
console.log(x);
}
example(); //Will print 10
Dans l'exemple ci-dessus, xest déclaré dans la portée globale. Toute portée enfant, telle que celle créée par la examplefonction, hérite effectivement des éléments déclarés dans toutes les portées parent (dans ce cas, il ne s'agit que de la portée globale).
Toute portée enfant qui redéclarera une variable déclarée dans la portée globale occultera la variable globale, provoquant potentiellement des bogues indésirables et difficiles à suivre:
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 du potentiel de causer des problèmes comme celui-ci. Si nous n'avions pas utilisé l' varinstruction dans la examplefonction, nous aurions accidentellement écrasé la valeur de xdans 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 le comprendre correctement, je vous suggère de passer par la spécification ECMAScript . Ce n'est peut-être pas la lecture la plus excitante, mais cela ne servira à rien.
Lorsque vous déclarez des variables globales, des fonctions, etc., elles, ehm, vont dans l'espace de noms global. Outre les problèmes de performances / mémoire (qui peuvent survenir), vous risquez de rencontrer des conflits de noms malheureux lorsque vous redéfinissez une variable importante ou n'utilisez pas la valeur que vous pensez utiliser.
Il faut éviter de définir des choses dans l'espace de noms global.