12

我正在阅读 David Mark 关于 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 问题的全局变量?)

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

4

3 回答 3

12

更新,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

参考:

于 2012-09-17T09:48:52.193 回答
0

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

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

window.foo 将简单地返回未定义。foo 将给出未定义的错误。所以是的,它们是不同的。但是在好的代码中(我的例子是非常糟糕的代码)看起来没有任何区别。(但如果有的话,我真的很想知道更多关于它的信息:))

于 2012-09-15T19:42:09.450 回答
-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 表达式应该成立。

于 2012-09-15T17:19:22.133 回答