What are the precise semantics of block-level functions in ES6?
我试图通过阅读原始规范来围绕ES6中新的标准化块级功能。我的肤浅理解是:
- ES6中允许块级函数声明。
- 他们升到了街区的顶部。
- 在严格模式下,它们在包含块外部不可见。
然而,由于这些语义的一部分被指定为"可选的"并且仅对于Web浏览器是必需的(附件B),因此这进一步复杂化。所以我想填写下表:
1 2 3 4 5 6 | | Visible outside of block? | Hoisted? Up to which point? | "TDZ"? | ------------------------------------------------------------------------------------------------------------------------ | Non-strict mode, no"web extensions" | | | | | Strict mode, no"web extensions" | | | | | Non strict mode, with"web extensions | | | | | Strict mode, with"web extensions" | | | | |
另外我不清楚在这种情况下"严格模式"是什么意思。这种区别似乎在附件B3.3中引入,作为函数声明的运行时执行的一些附加步骤的一部分:
1 2 | 1. If strict is false, then ... |
但是,据我所知,
1 2 3 4 5 | // Non-strict surrounding code { function foo() {"use strict";} } |
应该被认为是上表中的"严格模式"?然而,这与我最初的直觉相矛盾。
请记住,无论实际的实现不一致,我对ES6规范本身最感兴趣。
As far as I can see,
strict refers to the[[Strict]] internal slot of the function object.
没有。是的。它确实指的是包含函数声明的块发生的函数(或脚本)的严格性。不是要声明(或不是)声明的函数的严格性。
"web扩展"仅适用于草率(非严格)代码,并且仅当函数语句的外观是"理智"时 - 例如,如果其名称不与形式参数或词法冲突声明变量。
请注意,没有Web兼容性语义,strict和sloppy代码之间没有区别。在纯ES6中,块中的函数声明只有一种行为。
所以我们基本上有
1 2 3 4 5 6 | | web-compat pure -----------------+--------------------------------------------- strict mode ES6 | block hoisting block hoisting sloppy mode ES6 | it's complicated 1 block hoisting strict mode ES5 | undefined behavior 2 SyntaxError sloppy mode ES5 | undefined behavior 3 SyntaxError |
1:见下文。要求警告。
2:通常,抛出
3:ES5.1§12中的注释说明了"实现之间的重大且不可调和的变化"(例如这些)。建议使用警告。 sub>
那么现在具有Web兼容性的ES6实现如何在具有遗留语义的草率模式函数中的块中进行函数声明?
首先,纯语义仍然适用。也就是说,函数声明被提升到词块的顶部。
但是,还有一个
并且当评估函数声明时(在块中,就好像它像声明一样),将函数对象分配给该函数范围的变量。
这可以通过代码更好地解释:
1 2 3 4 5 6 7 8 9 | function enclosing(…) { … { … function compat(…) { … } … } … } |
与...一样的工作
1 2 3 4 5 6 7 8 9 10 11 | function enclosing(…) { var compat? = undefined; // function-scoped … { let compat? = function compat(…) { … }; // block-scoped … compat? = compat?; … } … } |
是的,这有点令人困惑,有两个不同的绑定(用下标0和1表示)具有相同的名称。所以现在我可以简洁地回答你的问题:
Visible outside of block?
是的,就像一个
Hoisted?
是的 - 两次。
Up to which point?
两者都是函数(但是用
"TDZ"?
不是在引用引用的词法声明的变量(
仅供参考:在ES6中,仅针对功能范围中的块指定了上述行为。由于ES7同样适用于
我不确定你的困惑来自哪里。根据10.2.1,非常清楚"在严格模式下"是什么或不是什么。在您的示例中,