在ECMAScript / Javascript 6中,是否需要在类周围使用IIFE?

8

如果我有

Class Car {}

我需要包装那个函数闭包吗?var变量会提升到window对象还是只在类中生效?当进行转译时呢?Traceur/babel会将其转换为IIFE并赋值给var变量吗?

我需要:

(function(){ 
    Class Car() {}
}());

要保持安全?

1
这将取决于您是将文件作为脚本加载还是作为模块加载。您是如何加载文件的? - loganfsmyth
本地环境下,这是一个非常好的问题。在这里使用Edge进行测试,虽然我可以有一个包含该类声明的car.js文件和一个使用该类的new-car.js文件,但如果我将Car记录到控制台中,它会显示构造函数,但如果我将window.Car记录到控制台中,它会显示undefined - Buzinas
@Buzinas:这有点不同。词法声明(classletconst)不会成为全局对象的属性。 - Felix Kling
@Buzinas和Felix Kling,都提出了非常好的观点和考虑,感谢你们的提醒。 - webdevinci
3个回答

4

这里展示的class car不需要使用IIFE包装器,事实上这会创建一个执行上下文并将该类隐藏在页面的其余部分中。

因此,您只需将其保留为(class car)即可(不是小写)。

class Car(){}

变量仍然像以前一样被提升。它将被提升到执行上下文的顶部。如果代码当前在窗口上下文中,则变量将在那里结束。

在ECMAScript 6中,类不会被提升。因此,只有在声明后才能使用该类。


类确实会被提升,这意味着在进入作用域时创建绑定,但未初始化。它的行为类似于let - Felix Kling
@FelixKling - 这是MDN上的说法。 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes “函数声明和类声明之间的一个重要区别在于函数声明被提升,而类声明不会。” 我理解错了吗?它似乎非常直接。 - Travis J
嗯,我指的是http://www.ecma-international.org/ecma-262/6.0/#sec-functiondeclarationinstantiation中第35步所写的内容。但我猜“提升”可能有不同的含义(也许?)。在规范中,类和`let`声明绝对不被视为可提升声明,所以我想我错了。然而,即使在规范中,似乎也没有明确描述“提升”这个术语。 - Felix Kling
@FelixKling - 对我来说有点困惑。我看了一下类被转译成什么,它似乎只是一个类似于jQuery的IIFE,并返回一个实例化对象。但是我认为返回值必须在某个地方提升。我不确定,也没有任何es6的实际测试来验证。 - Travis J
我想我有点含糊不清,问了两个问题。一个是关于ECMAScript 6的工作原理,另一个是babel如何进行转译(也就是是否将类附加到window对象上)。 顺便说一下,在研究过程中,我发现“let”不像变量那样提升,它们在声明的位置声明...很有趣。谢谢大家的帮助。 - webdevinci

2
你可以在这里查看Babel将你的代码转换成什么样子:这里 除非你想隐藏类并生成var Class,否则不需要使用IIFE。生成的变量会像任何变量一样被提升:声明会在开头进行,但赋值会在原始行中进行。
是的,Babel将let转换为var,但它还会处理额外的赋值以使作用域按预期工作。如果你只想编写ES6代码并执行它,就不必担心这些细节,只需遵循ES6(ES2015)标准即可。

1
不,只要它被视为ES6模块中的代码,就没有必要像那样进行包装。Babel的默认设置将输入代码和文件视为模块。Babel在各个位置引入函数来实现正确的作用域语义,并且如果您启用了适当的转换器,则会将let转换为var
ES6模块始终处于严格模式下,这是规范对严格模式下赋值的说明:“对未声明的标识符或无法解析的引用的赋值不会创建全局对象中的属性。在严格模式代码中发生简单赋值时,其左侧不得评估为无法解析的引用。”

http://www.ecma-international.org/ecma-262/6.0/#sec-strict-mode-of-ecmascript

你的意思是什么?

var变量是否会被提升到[...]类中?


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