O que significa que o namespace global seria poluído?
Eu realmente não entendo o que significa um namespace global ficar poluído.
Respostas:
Nota rápida sobre coleta de lixo
À medida que as variáveis perdem o escopo, elas se qualificam para a coleta de lixo. Se eles tiverem escopo global, eles não serão elegíveis para coleta até que o namespace global perca o escopo.
Aqui está um exemplo:
var arra = [];
for (var i = 0; i < 2003000; i++) {
arra.push(i * i + i);
}
Adicionar isso ao seu namespace global (pelo menos para mim) deve adicionar 10.000 kb de uso de memória (win7 firefox), que não será coletado. Outros navegadores podem lidar com isso de forma diferente.
Considerando que ter o mesmo código em um escopo que sai do escopo como este:
(function(){
var arra = [];
for (var i = 0; i < 2003000; i++) {
arra.push(i * i + i);
}
})();
Permitirá arraperder o escopo após a execução do fechamento e será elegível para a coleta de lixo.
Namespace global é seu amigo
Apesar das muitas reclamações contra o uso do namespace global, ele é seu amigo. E como um bom amigo, você não deve abusar de seu relacionamento.
Seja gentil
Não abuse (geralmente referido como "poluente") do namespace global. E o que quero dizer com não abuse do namespace global é - não crie múltiplas variáveis globais. Aqui está um exemplo ruim de uso do namespace 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);
Isso vai criar 11 variáveis globais que podem ser substituídas ou mal interpretadas em algum lugar.
Seja engenhoso
Uma abordagem mais engenhosa, que não polui o namespace global, seria envolver tudo isso no padrão do módulo e usar apenas uma variável global ao expor várias variáveis.
Aqui está um exemplo: (observe que isso é simples e não há tratamento de erros)
//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()fora do escopo? Seria muito perfeito compreender outro conceito próximo a esta problemática!
Em JavaScript, as declarações fora de uma função estão no escopo global. Considere este pequeno exemplo:
var x = 10;
function example() {
console.log(x);
}
example(); //Will print 10
No exemplo acima, xé declarado no escopo global. Qualquer escopo filho, como aquele criado pela examplefunção, herda efetivamente coisas declaradas em qualquer escopo pai (neste caso, é apenas o escopo global).
Qualquer escopo filho que declara novamente uma variável declarada no escopo global irá sombrear a variável global, potencialmente causando bugs indesejados e difíceis de rastrear:
var x = 10;
function example() {
var x = 20;
console.log(x); //Prints 20
}
example();
console.log(x); //Prints 10
Variáveis globais geralmente não são recomendadas devido ao potencial de causar problemas como este. Se não usássemos a varinstrução dentro da examplefunção, teríamos substituído acidentalmente o valor de xno escopo global:
var x = 10;
function example() {
x = 20; //Oops, no var statement
console.log(x); //Prints 20
}
example();
console.log(x); //Prints 20... oh dear
Se você quiser ler mais e entendê-lo corretamente, sugiro passar pela especificação ECMAScript . Pode não ser a mais emocionante das leituras, mas não terá fim.
Quando você declara variáveis globais, funções, etc., elas, ehm, vão para o namespace global. Além de problemas de desempenho / memória (que podem surgir), é provável que você se depare com conflitos de nomes infelizes, quando redefinir uma variável importante ou não usar o valor que pensa usar.
Definir coisas no namespace global deve ser evitado.