我试图通过阅读原始规范来绕过ES6中新的标准化块级功能。我的肤浅理解是:
然而,由于这些语义的一部分被指定为"可选"并且仅对Web浏览器是必需的(Annex B)。所以我想填写下表:
| 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" | | | |
另外我不清楚什么"严格模式"意味着在这种情况下。这种区别似乎是在Annex B3.3中引入的,作为函数声明的运行时执行的一些附加步骤的一部分:
1. If strict is false, then
...
但是,据我所知,strict
指的是函数对象的[[Strict]]
内部插槽。这是否意味着:
// Non-strict surrounding code
{
function foo() {"use strict";}
}
应该考虑"严格模式"在上表中?然而,这与我最初的直觉相矛盾。
请注意,我对ES6规范本身最感兴趣,而不管实际的实现不一致。
答案 0 :(得分:24)
据我所知,
strict
指的是函数对象的[[Strict]]
内部插槽。
没有。是的。它确实引用了函数(or script)的严格性,其中包含函数声明的块发生。不是要声明(或不是)声明的函数的严格性。
“网络扩展”仅适用于草率(非严格)代码,并且仅当函数语句的外观是“理智”时 - 例如,如果其名称不与正式名称冲突参数或词汇声明的变量。
请注意,没有Web兼容性语义,strict和sloppy代码之间没有区别。在纯ES6中,块中的函数声明只有一种行为。
所以我们基本上有
| web-compat pure
-----------------+---------------------------------------------
strict mode ES6 | block hoisting block hoisting
sloppy mode ES6 | it's complicated ¹ block hoisting
strict mode ES5 | undefined behavior ² SyntaxError
sloppy mode ES5 | undefined behavior ³ SyntaxError
1:见下文。要求警告。
2:通常,抛出SyntaxError
3:ES5.1 §12中的注释说明了“实现之间重要且不可调和的变化”(例如these)。建议发出警告。
那么现在具有Web兼容性的ES6实现如何在带有遗留语义的草率模式函数中的块中进行函数声明?
首先,纯语义仍然适用。也就是说,函数声明被提升到词块的顶部
但是,还有一个 var
声明,它被提升到封闭功能的顶部。
当评估函数声明时(在块中,好像它像声明一样被满足),函数对象被赋值到该函数范围的变量。
代码更好地解释了这一点:
function enclosing(…) {
…
{
…
function compat(…) { … }
…
}
…
}
与
的作用相同function enclosing(…) {
var compat₀ = undefined; // function-scoped
…
{
let compat₁ = function compat(…) { … }; // block-scoped
…
compat₀ = compat₁;
…
}
…
}
是的,这有点令人困惑,有两个不同的绑定(用下标0和1表示)具有相同的名称。所以现在我可以简洁地回答你的问题:
在街区之外可见吗?
是的,就像var
一样。但是,第二个绑定仅在块内可见。
悬挂?
是的 - 两次。
到底是哪一点?
函数(无论是用undefined
初始化)和块(用函数对象初始化)。
“TDZ”?
不是在引用引用的词法声明变量(let
/ const
/ class
)的时间死区的意义上,不是。但是在执行body之前遇到函数声明之前,函数范围的变量是undefined
(特别是在块之前),如果你试图调用它,你也会得到一个异常。
答案 1 :(得分:1)
我不确定你的困惑来自哪里。根据{{3}},很明显“严格模式”是什么或不是什么。在您的示例中,foo
的{{1}}内部广告位确实是[[Strict]]
并且将处于严格模式,但托管它的广告块不会。第一句(您引用的那个)与托管块有关,而不是与其中生成的内容有关。片段中的块不是严格模式,因此该部分适用于它。