全局命名空间会被污染是什么意思?

the*_*ava 87 javascript

全局命名空间会被污染是什么意思?

我真的不明白受污染的全局命名空间意味着什么.

Tra*_*s J 120

关于垃圾收集的快速说明

随着变量失去范围,它们将有资格进行垃圾收集.如果它们是全局范围的,则在全局命名空间失去范围之前它们将不具有收集资格.

这是一个例子:

var arra = [];
for (var i = 0; i < 2003000; i++) {
 arra.push(i * i + i);
}
Run Code Online (Sandbox Code Playgroud)

将此添加到您的全局命名空间(至少对我来说)应该不会收集10,000 kb的内存使用量(win7 firefox).其他浏览器可以不同地处理它.

而在范围超出范围的相同代码中,如下所示:

(function(){
 var arra = [];
 for (var i = 0; i < 2003000; i++) {
  arra.push(i * i + i);
 }
})();
Run Code Online (Sandbox Code Playgroud)

允许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);
Run Code Online (Sandbox Code Playgroud)

这将创建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());
})();
Run Code Online (Sandbox Code Playgroud)

  • 将变量保存在闭包内可确保它们被垃圾收集. (9认同)
  • 一个非常有趣的答案,您能解释一下使用像您在范围内所做的那样的收益,并在范围外使用例如Calculate.prototype.Slope()来区别什么吗?补充另一个与这个问题有关的概念将是非常完美的! (2认同)

Jam*_*ice 20

在JavaScript中,函数外部的声明属于全局范围.考虑这个小例子:

var x = 10;
function example() {
    console.log(x);
}
example(); //Will print 10
Run Code Online (Sandbox Code Playgroud)

在上面的示例中,x在全局范围内声明.任何子作用域(例如由example函数创建的作用域)都有效地继承在任何父作用域中声明的内容(在这种情况下,这只是全局作用域).

重新声明在全局范围内声明的变量的任何子范围都将影响全局变量,从而可能导致不需要的,难以跟踪的错误:

var x = 10;
function example() {
    var x = 20;
    console.log(x); //Prints 20
}
example();
console.log(x); //Prints 10
Run Code Online (Sandbox Code Playgroud)

通常不建议使用全局变量,因为这可能会导致这样的问题.如果我们没有varexample函数内部使用语句,我们会不小心覆盖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
Run Code Online (Sandbox Code Playgroud)

如果您想要阅读更多并正确理解它,我建议您阅读ECMAScript规范.它可能不是最令人兴奋的阅读,但它将无助于结束.


Ser*_*sev 8

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

应避免在全局命名空间中定义事物.