JavaScript全局对象

6
经常看到JavaScript代码中定义全局对象作为命名空间。
var MyNS = {a: function() {}, ... };

但有时候我看到人们省略了“var”关键字,比如:

MyNS = {a: function() {}, ...};

我相信在web浏览器中,如果你没有使用var关键字定义一个变量,它会被放置在window对象中,这个对象充当全局命名空间。既然省略"var"可以节省一些文本字节,那么有没有必要特别针对这个目的使用这个关键字呢?

4个回答

8
由于不使用“var”可以节省一些文本字节,因此有理由为此特定目的使用关键字吗?
即使您在全局代码上,我也不建议您避免使用“var”关键字。
这两种方法看起来相似,但实际上它们并不相同。第一种是变量声明,全局代码上的变量对象是全局对象本身,这就是为什么全局变量可以作为全局对象的属性(window.MyNS)访问。
第二个是未声明的赋值,如果在作用域链中找不到标识符,则会在全局对象上创建一个属性。
避免使用它的真正原因是,在语言的新标准ECMAScript 5th Edition中,在严格模式下,对未声明的标识符进行赋值将抛出ReferenceError,从而破坏您的代码。
您的两个示例之间还有另一个微妙的区别,变量实例化创建的属性是不可删除的全局对象上的属性:
var myVar = '';
delete window.myVar; // false
typeof window.myVar; // 'string'

当未声明的赋值不成立时:

myProp = '';
delete window.myProp; // true
typeof window.myProp; // 'undefined'

推荐文章:


1
+1 - 不仅如此,这样做只是很草率。如果你想节省一些字节,只需压缩代码即可。 - ChaosPandion
那我们是否可以通过 window.MyNS={}; 声明全局变量,并且具有与 var MyNS={}; 相同的含义呢? - c4il
2
@Piccolo,嗯,不完全是“一样的”,window.MyNS = {};会在全局对象上创建一个属性,而var MyNS = {};将声明一个变量,并且作为全局对象,是全局执行上下文的变量对象,因此也会创建一个全局属性,我建议您查看我在答案中链接的文章。 - Christian C. Salvadó

2
var的使用定义了当前作用域中的局部变量。如果您在全局作用域中,它们实际上是等效的。在那里使用var更多的是为了可读性和可维护性,因为意图是非常明确的。如果没有初始化var,就不太清晰了。
在任何局部作用域中,如果MyNS在作用域链的某个地方被初始化,您将覆盖该局部变量而不是定义全局变量。

0

我认为使用关键字是很好的习惯,因为它可以让你养成习惯,并在函数体内遗忘时帮助防止恶意错误。另外,如果一些全局代码发现自己被迁移到函数中,这也很好。

但不,它并非绝对必要。

编辑 — @eyelidlessness有一个非常好的观点,但如果你已经在全局级别上输入代码,这不是一个问题。

我见过的一个相当牢固的模式是以类似以下方式初始化全局命名空间:

(function(window, undefined) {

  var foo = { stuff: "in my namespace", ... };

  window.foo = foo;
})(this);

在全局范围内,this将是窗口对象(如果您在浏览器中;如果不是,则是该上下文中的全局对象)。


-1

2
我是Crockford先生的粉丝,但在我看来,这是他最糟糕的文章之一。他描述的三种方式并不完全等价,并且在ES5严格模式下使用未声明的赋值(第三种方式)存在可能的危险。此外,他的JSLint工具鼓励使用"use strict"指令,但几乎没有检查严格模式的任何规则。:( - Christian C. Salvadó
我认为值得补充的是(显然),这篇文章是2008年的,因此自那时以来已经发生了很多变化,这也就不足为奇了。我目前正在阅读《JavaScript权威指南》(作者Crockford,同样出版于2008年),到目前为止,我遇到了几个让我困惑了几个小时的章节。这本书被广泛推荐用于提高你的JavaScript技能,但它早在2年前就应该推出第二版了! - delta9

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接