首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >什么是全局名称空间会被污染?

什么是全局名称空间会被污染?
EN

Stack Overflow用户
提问于 2012-01-14 14:00:33
回答 3查看 35.3K关注 0票数 106

,什么是全局名称空间会被污染?

我真的不明白全局名称空间被污染意味着什么。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-11-12 21:54:26

关于垃圾收集的快速说明

当变量失去作用域时,它们将有资格进行垃圾收集。如果它们是全局范围的,则在全局命名空间失去作用域之前,它们将不符合收集条件。

下面是一个示例:

代码语言:javascript
复制
var arra = [];
for (var i = 0; i < 2003000; i++) {
 arra.push(i * i + i);
}

将其添加到全局命名空间(至少对我来说)应该会添加10,000 kb的内存使用情况(win7 firefox),这将不会被收集。其他浏览器可能以不同的方式处理这一问题。

然而,在超出作用域的作用域中有相同的代码,如下所示:

代码语言:javascript
复制
(function(){
 var arra = [];
 for (var i = 0; i < 2003000; i++) {
  arra.push(i * i + i);
 }
})();

将允许arra在闭包执行后失去作用域,并有资格进行垃圾收集。

全球名称空间是你的朋友

尽管有许多反对使用全局命名空间的声明,但它是您的朋友。就像一个好朋友,你不应该滥用你们的关系。

Be Gentle

不要滥用全局名称空间(通常称为“污染”)。我的意思是不要滥用全局名称空间,不要创建多个全局变量。下面是一个使用全局命名空间的糟糕示例。

代码语言:javascript
复制
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个全局变量,这些变量可能会被改写或在某个地方被误解。

资源丰富的

一种更足智多谋的方法不会污染全局名称空间,它将所有这些都封装在模块模式中,并且在公开多个变量时只使用一个全局变量。

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

代码语言:javascript
复制
//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());
})();
票数 140
EN

Stack Overflow用户

发布于 2012-01-14 14:09:53

在JavaScript中,函数之外的声明在全局范围内。考虑一下这个小例子:

代码语言:javascript
复制
var x = 10;
function example() {
    console.log(x);
}
example(); //Will print 10

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

任何重新声明全局范围中声明的变量的子作用域都会隐藏全局变量,可能会导致不必要的、难以跟踪的bug:

代码语言:javascript
复制
var x = 10;
function example() {
    var x = 20;
    console.log(x); //Prints 20
}
example();
console.log(x); //Prints 10

通常不推荐全局变量,因为可能会导致这样的问题。如果我们没有在var函数中使用example语句,我们就会意外地覆盖全局范围中x的值:

代码语言:javascript
复制
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规范。它可能不是最令人兴奋的阅读,但它将帮助无止境。

票数 21
EN

Stack Overflow用户

发布于 2012-01-14 14:03:06

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

应该避免在全局命名空间中定义内容。

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8862665

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档