我真的不了解被污染的全局名称空间是什么意思。

评论

链接以供将来参考:JavaScript命名空间声明

#1 楼

有关垃圾回收的快速说明

由于变量失去作用域,它们将有资格进行垃圾回收。如果它们是全局范围的,则只有在全局名称空间失去范围之前,它们才有资格进行收集。

这里是一个示例:

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个全局变量,这些变量可能在某个地方被覆盖或误解。
<变得资源丰富

一种更加资源丰富的方法,它不会污染全局名称空间,而是将其全部包装在模块模式中,并且在暴露多个变量时仅使用一个全局变量。

以下是一个示例:(请注意,这很简单,没有错误处理)

//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());
})();


评论


将变量保留在闭包内可确保它们被垃圾回收。

– Java
2012年11月13日,0:23

非常有趣的答案,您能解释一下使用像您在范围中所做的那样的返回值,并在范围之外使用例如Calculate.prototype.Slope()有什么区别?完善另一个接近这个问题的概念将是非常完美的!

–Ludo
2013年1月11日在8:55



感谢您的良好解释。快速问题:您希望看到该代码段中的错误处理内容吗?

–圣淘沙
2014年8月15日14:54



@Sentenza-这取决于如果发生错误会发生什么情况。如果什么都没有,那么它实际上不需要错误处理。如果这很重要,那么也许要进行一些测试以确保不会被0除,并且会显示一条消息或响应以指示失败的尝试(有时这仅表示无提示失败)。也许进行一些测试以确保数字实际上是数字而不是文本。总体而言,错误处理还取决于谁在使用代码。如果只是您,您可能会知道不传递某些令人不快的论点。这也是一个相当简单的示例:)

–特拉维斯J
2014年8月15日19:55

#2 楼

在JavaScript中,函数外部的声明在全局范围内。考虑下面的小示例:在上面的示例中,在全局范围中声明了x。任何子范围,例如由example函数创建的子范围,都有效地继承了在任何父范围中声明的内容(在这种情况下,这只是全局范围)。

任何子范围重新声明在中声明的变量全局作用域将掩盖全局变量,从而可能导致不必要的,难以跟踪的错误:

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


通常不建议使用全局变量,因为它可能会引起类似这样的问题。如果不在var函数中使用example语句,则可能会意外覆盖全局范围内的x的值:

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


如果要阅读要进一步了解并正确理解它,我建议您仔细阅读ECMAScript规范。它可能不是最令人兴奋的读物,但无济于事。

#3 楼

声明全局变量,函数等时,它们会转到全局名称空间。除了性能/内存问题(可能会出现)之外,当您重新定义重要变量或不使用您认为要使用的值时,很可能会遇到不幸的名称冲突。

定义避免在全局命名空间中发生任何事情。

评论


避免在全局名称空间中定义内容的一种方法是使用局部变量(在函数内部用“ var”声明),但是变量对函数而言是局部的。应该尽可能地做到这一点。

–StéphaneGlondu
2012年1月14日14:06