全局变量和全局对象的属性之间是否存在任何差异

时间:2012-09-15 16:47:47

标签: javascript global-variables

我正在阅读大卫马克关于js框架“Sencha”的以下分析:https://gist.github.com/3279190并且在那里他说......

  

他们想要的是一个全局变量,但他们最终得到的是全局对象的属性。根据规范和(以及实施历史),两者之间存在足够的差异,需要注意不要混淆它们(如此处所做的那样)。

...但据我所知,var my_global = 123;和(在浏览器环境中)window.my_global = 123;之间没有任何区别(在该示例中,我假设环境是浏览器 - 因此使用window,但我本来可以使用this.my_global,因为在不同的环境中运行时,全局对象显然会有所不同。

但忽略这种微小的差异是否将属性分配给全局对象和创建全局变量之间存在差异?我没想过,创建全局变量只是将属性分配给全局对象的另一种方法。

我相信在某些浏览器中如果有一个id为“my_global”的元素可能会出现问题,那么显然可能会导致JavaScript引用正确的问题,但我不确定是怎么/导致该问题的原因(例如,为全局对象分配属性会导致元素ID问题发生,还是声明导致元素ID问题的全局变量?)

有人可以为我澄清一下吗?

3 个答案:

答案 0 :(得分:10)

在全局范围内使用var创建的变量确实会创建全局对象的属性。但是,此属性与尚未使用var创建的全局对象的属性具有不同的行为。

首先,执行变量声明的方式不同:全局作用域中的var语句在执行任何代码之前创建全局对象的属性,这种效应通常称为提升,在网络上有详细记录(参见下面的参考资料)。

其次,全局变量与使用var创建的全局对象的属性不同,不能使用delete运算符删除(尽管这是not true in older versions of IE)。 delete不能用于删除变量。这种差异低至每个对象属性所具有的内部property attributes。这些属性在ECMAScript规范中指定。在ECMAScript 5术语中,var foo = "bar"使用foo属性[[Configurable]]创建全局对象的属性false,而this.foo = "bar"(在全局范围内)创建foo 1}} [[Configurable]]属性true的属性。

参考文献:

答案 1 :(得分:0)

我不知道任何实际差异,但确实在引用为全局或window.var之间存在一些差异。一个简单的例子:

'use_strict';
console.info(window.foo);
console.info(foo);

window.foo将只返回undefined。 foo会将undefined视为错误。 所以,是的,他们是不同的。但是在良好的代码中(我的代码是非常糟糕的代码)它看起来并没有任何区别。 (但如果有,我真的想知道更多关于它:))

答案 2 :(得分:-2)

var count = 123

var global_object = {
    count:var = 456
console.log(this.count) //returns 456

}

console.log(count) //returns 123

console.log(global_object) //returns 456

在上面,count首先被定义为全局变量。然后,它被定义为全局对象中的属性。全局对象中的定义是该对象的本地定义。

我现在看到我的回答有问题,当我第一次发布这个时,我没有想到。在上面最受欢迎的答案中,我注意到,正确地说,在问题中的全局变量的情况下,在其定义中使用“var”,但在全局对象的情况下,不使用“var”。我仍然期望在这里发挥作用(它将在ActionScript中)。

上面的示例我还有其他一些问题。 count:var =对我来说是错的。也许那应该是var count = 456.但是;我仍然希望函数内声明的变量只在该函数中具有范围。因此示例中的console.log表达式应该为true。