我正在阅读大卫马克关于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问题的全局变量?)
有人可以为我澄清一下吗?
答案 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
的属性。
参考文献:
德米特里·索斯尼科夫(Dmitry Soshnikov)在他的出色表现中详细讲述了这一点 系列文章,ECMAScript 262-3 in detail。我建议 阅读第2章的全部内容,但最相关的部分被称为 About Variables
之前链接的kangax article包含很多内容
浏览器错误和偏差的相关信息和详细信息,
加上关于window
的进一步怪癖。
Angus Croll的Variables vs. Properties in JavaScript article,链接到许多与此答案相同的资源。
规范:ECMAScript 5.1。
答案 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。