我读到以下David Mark关于js框架 "Sencha "的分析。https:/gist.github.com3279190 在那里他说...
他们想要的是一个全局变量,但他们最终得到的是全局对象的一个属性。根据规范和(以及实现历史),两者之间有足够的差异,需要注意不要把它们混为一谈(就像这里做的那样)。
....但据我所知,这两者之间没有任何区别。var my_global = 123;
和(在浏览器环境下) window.my_global = 123;
(在那个例子中,我假设环境是浏览器--因此使用了 window
但我可以只用 this.my_global
而不是全局对象,因为显然全局对象在不同的环境中运行时会有所不同)。)
但是忽略这个小差异,将一个属性分配给全局对象和创建一个全局变量之间有什么区别吗?我以为没有,创建全局变量只是将属性分配给全局对象的另一种方式。
我相信在某些浏览器中可能会有一个问题,如果他们有一个id为 "my_global "的元素,那么显然会导致JavaScript引用正确的问题,但我不知道是怎么what导致这个问题的(例如,给Global Object分配一个属性是否会导致元素id问题的发生,或者是声明一个全局变量导致元素id问题?
谁能帮我澄清一下?
更新,2020年4月
正如D.Pardal在评论中所指出的那样,下面第一句话写于2012年,在支持以下内容的环境中不再总是正确的。ES模块. 在一个ES模块中,一个 var
语句不会产生全局对象的属性。
原始答案
一个使用 var
在全局作用域中确实创建了全局对象的一个属性。但是,这个属性的行为与没有使用 var
.
首先,变量声明的执行方式是不同的:在全局范围内的语句在执行任何代码之前就创建了一个全局对象的属性。var
全局范围内的语句在执行任何代码之前就创建了全局对象的属性,这种效果通常被称为 "变量声明"。吊装,在网上有很好的记录(见下面的参考资料)。
其次,全局变量与全局对象的属性不同,它没有用 var
不能使用 delete
运算符(虽然这是 在旧版本的IE中不是这样). delete
不能用于删除变量。这种差异是由于内部的 属性 每个对象属性都有。这些属性在ECMAScript规范中被指定。在ECMAScript 5术语中。var foo = "bar"
创建一个属性 foo
的全局对象。[[Configurable]]
属性 false
而 this.foo = "bar"
在全局范围内)创建一个 foo
财产 [[Configurable]]
属性 true
.
参考文献。
德米特里-索什尼科夫在他的一系列优秀文章中对此作了详细的阐述。ECMAScript 262-3详解. 我建议读完第二章的所有内容,但最相关的一节是所谓的...关于变量.
该 江湖文章 前面链接的内容包含了很多相关信息和浏览器错误和偏差的细节,以及更多有关的怪癖。window
.
安格斯-克罗尔 JavaScript文章中的变量与属性,其中链接到许多与本答案相同的资源。
该规范。ECMAScript 5.1.
我不知道有什么实际的区别,但引用为全局或为window.var肯定有一些区别。举个简单的例子。
'use_strict';
console.info(window.foo);
console.info(foo);
window.foo会简单地返回undefined.foo会给出undefined的错误信息,所以是的,它们是不同的。但在好的代码中(我的例子是非常糟糕的代码),它看起来没有任何区别。(但如果有的话,我真的很想知道更多关于它的信息:) )
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 表达式应该是正确的。