全局命名空间会被污染是什么意思?
我真的不明白全局命名空间被污染意味着什么。
全局命名空间会被污染是什么意思?
我真的不明白全局命名空间被污染意味着什么。
关于垃圾收集的快速说明
当变量失去作用域时,它们将有资格进行垃圾收集。如果它们是全局范围的,那么在全局命名空间失去范围之前,它们将不符合收集条件。
下面是一个例子:
var arra = [];
for (var i = 0; i < 2003000; i++) {
arra.push(i * i + i);
}
将此添加到您的全局命名空间(至少对我而言)应该会占用 10,000 kb 的内存使用量(win7 firefox),这将不会被收集。其他浏览器可能会有不同的处理方式。
而在超出范围的范围内具有相同的代码,如下所示:
(function(){
var arra = [];
for (var i = 0; i < 2003000; i++) {
arra.push(i * i + i);
}
})();
将允许arra
在闭包执行后失去作用域并有资格进行垃圾收集。
全局命名空间是你的朋友
尽管有许多反对使用全局命名空间的说法,但它是您的朋友。就像一个好朋友一样,你不应该滥用你们的关系。
要温柔
不要滥用(通常称为“污染”)全局命名空间。我的意思是不要滥用全局命名空间 - 不要创建多个全局变量。这是使用全局命名空间的一个不好的例子。
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);
这将创建 11 个全局变量,这些变量可能在某处被覆盖或误解。
足智多谋
一种不会污染全局命名空间的更有效的方法是将所有这些都包装在module模式中,并且只使用一个全局变量,同时公开多个变量。
这是一个例子:(请注意这很简单,没有错误处理)
//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());
})();
在 JavaScript 中,函数外部的声明在全局范围内。考虑这个小例子:
var x = 10;
function example() {
console.log(x);
}
example(); //Will print 10
在上面的例子中,x
是在全局范围内声明的。任何子作用域,例如由example
函数创建的子作用域,都有效地继承了在任何父作用域中声明的东西(在这种情况下,这只是全局作用域)。
任何重新声明在全局作用域中声明的变量的子作用域都会影响全局变量,可能会导致不需要的、难以跟踪的错误:
var x = 10;
function example() {
var x = 20;
console.log(x); //Prints 20
}
example();
console.log(x); //Prints 10
通常不推荐使用全局变量,因为它有可能导致这样的问题。如果我们没有var
在example
函数内部使用该语句,我们会不小心覆盖x
全局范围内的值:
var x = 10;
function example() {
x = 20; //Oops, no var statement
console.log(x); //Prints 20
}
example();
console.log(x); //Prints 20... oh dear
如果您想阅读更多并正确理解它,我建议您阅读ECMAScript 规范。它可能不是最令人兴奋的阅读,但它无济于事。
当您声明全局变量、函数等时,它们,嗯,转到全局命名空间。除了性能/内存问题(可能会出现)之外,当您重新定义一个重要变量或不使用您认为使用的值时,您可能会遇到不幸的名称冲突。
应避免在全局命名空间中定义事物。