ECMAScript 6模块中的变量声明是否成为window属性?

3
在 ECMAScript 5 及以下版本中,在脚本顶层使用 var 声明会变为全局变量,也就是说它们会成为全局对象 (window 在浏览器中的表示方式) 的属性。但在 ECMAScript 6 中,我们引入了模块化。模块化默认为严格模式,因此如果我们忘记使用 var 来声明变量,不会自动创建全局变量。但如果我在一个模块的顶层位置使用 var 声明变量,它是否会成为 window 对象的全局属性?那么如果我使用新添加到 ES6 中的 letconst 或其他声明形式呢?
var foo = {};
console.log(window.foo === foo); // true or false?

let bar = {};
console.log(window.bar === bar); // what about this?

@Bergi:我认为这不是重复的问题。那个问题询问脚本上下文中的“let”。而这个问题询问模块上下文中的“var”。 - Sean McMillan
有没有一种有用的方法,我可以编辑这个问题来强调区别?我觉得仅仅添加“注意,在模块上下文中的VAR”(或其他类似的东西)不太合适,因为那基本上是对版主的无礼。但我不确定如何更明确地澄清这个区别,使它自然地成为问题的一部分。 - Sean McMillan
1
这看起来更像是重复的问题:https://dev59.com/sI_ea4cB1Zd3GeqPS8zt?rq=1,尽管存在一些细微差异。(我想知道它们是否在“window”中;那个问题是在问是否有类似于模块的“window”东西。对于两者的答案都是相同的。) - Sean McMillan
哦,对不起。可能是我太累了 :-/ - Bergi
没问题。这是一个微妙的区别。 - Sean McMillan
1个回答

2
“但是,如果我在模块的顶层声明一个变量,它会成为窗口对象的全局属性吗?如果我使用let、const或es6中添加的任何新声明形式呢?”答案是在这两种情况下都不是。只有存在 script 声明时(第15.1.8节),才会创建全局属性(如果 CanDeclareGlobalVar 返回true)。但是,模块内的VarDeclaredNamesVarScopedDeclarations 属于该模块(确切地说,属于ModuleItem)而不是整个脚本。

如果不是这样的话,那么将数据封装在模块内(以便每个模块通过已建立的export/import例程与应用程序的其余部分进行通信)的整个想法都将被浪费。


1
我无法理解规范文本,我没有看到在15.1.8中它检查脚本与模块的地方。我想我需要先提高自己的能力水平。不过,你用简单明了的英语表达“如果这样做,模块就毫无意义”确实很有道理。 - Sean McMillan

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