【问题标题】:What does it mean global namespace would be polluted?全局命名空间会被污染是什么意思?
【发布时间】:2012-02-10 08:53:19
【问题描述】:

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

我真的不明白被污染的全局命名空间是什么意思。

【问题讨论】:

标签: 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());
})();

【讨论】:

  • 将变量保存在闭包中可确保它们被垃圾回收。
  • 非常有趣的答案,你能解释一下在你的范围内使用 return 和在范围外使用例如 Calculate.prototype.Slope() 有什么区别吗?理解另一个接近这个问题的概念将是非常完美的!
  • 感谢您的精彩解释。快速提问:您希望看到关于该 sn-p 中的错误处理的哪些内容?
  • @Sentenza - 这取决于如果出现错误会发生什么。如果什么都没有,那么它真的不需要错误处理。如果它很重要,那么可能会进行一些测试以确保不会发生除以 0 的情况,以及指示失败尝试的消息或响应(有时这只是意味着静默失败)。也许进行一些测试以确保数字实际上是数字而不是文本。总的来说,错误处理还取决于谁在使用代码。如果只有你,你可能会知道不要传递某些破坏性的论点。这也是一个相当简单的例子:)
【解决方案2】:

在 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

通常不推荐使用全局变量,因为可能会导致此类问题。如果我们没有在example 函数中使用var 语句,我们会不小心覆盖全局范围内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 specification。这可能不是最令人兴奋的阅读,但它会帮助无穷。

【讨论】:

    【解决方案3】:

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

    要避免在全局命名空间中定义事物。

    【讨论】:

    • 避免在全局命名空间中定义事物的一种方法是使用局部变量(在函数内用“var”声明),但是变量是......函数的局部变量。应该尽可能做到这一点。
    猜你喜欢
    • 2017-05-15
    • 1970-01-01
    • 2014-04-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多