What does it mean global namespace would be polluted?
它意味着什么全局命名空间会被污染?
我真的不明白被污染的全球名称空间意味着什么。
垃圾收集速记
当变量失去作用域时,它们将符合垃圾收集的条件。如果它们的作用域是全局的,那么在全局命名空间失去作用域之前,它们将不符合收集条件。
下面是一个例子:
1 2 3 4 | var arra = []; for (var i = 0; i < 2003000; i++) { arra.push(i * i + i); } |
将此添加到全局命名空间(至少对我而言)会导致10000 KB的内存使用(win7 firefox),而这将不会被收集。其他浏览器可能会以不同的方式处理这一问题。
而在这样一个超出范围的范围内拥有相同的代码:
1 2 3 4 5 6 | (function(){ var arra = []; for (var i = 0; i < 2003000; i++) { arra.push(i * i + i); } })(); |
将允许
全局命名空间是您的朋友
尽管有许多人反对使用全局命名空间,但它是您的朋友。像一个好朋友一样,你不应该滥用你的关系。
温柔
不要滥用(通常称为"污染")全球名称空间。我的意思是不要滥用全局名称空间,不要创建多个全局变量。下面是一个使用全局命名空间的错误示例。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 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个全局变量,这些变量可能在某个地方被覆盖或误解。
足智多谋
一种资源更丰富的方法,它不会污染全局名称空间,将所有这些都包装在模块模式中,并且在公开多个变量时只使用一个全局变量。
下面是一个例子:(请注意这很简单,没有错误处理)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | //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中,函数外部的声明在全局范围内。考虑这个小例子:
1 2 3 4 5 | var x = 10; function example() { console.log(x); } example(); //Will print 10 |
在上面的示例中,
重新声明全局范围中声明的变量的任何子范围都将隐藏全局变量,可能导致不需要的、难以跟踪的错误:
1 2 3 4 5 6 7 | var x = 10; function example() { var x = 20; console.log(x); //Prints 20 } example(); console.log(x); //Prints 10 |
通常不建议使用全局变量,因为这样可能导致问题。如果我们没有在
1 2 3 4 5 6 7 | 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规范。这可能不是最令人兴奋的阅读,但它将无济于事。
当您声明全局变量、函数等时,它们(ehm)将转到全局命名空间。除了性能/内存问题(可能会出现),当您重新定义一个重要变量或使用您认为使用的值时,很可能会遇到不幸的名称冲突。
应避免在全局命名空间中定义内容。