rvi*_*dal 19 javascript formal-semantics ecmascript-6
我试图通过阅读原始规范来围绕ES6中新的标准化块级功能.我的肤浅理解是:
然而,由于这些语义的一部分被指定为"可选的"并且仅对于Web浏览器是必需的(附件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" | | | |
另外我不清楚在这种情况下"严格模式"是什么意思.这种区别似乎在附件B3.3中引入,作为函数声明的运行时执行的一些附加步骤的一部分:
1. If strict is false, then
...
Run Code Online (Sandbox Code Playgroud)
但是,据我所知,strict
指[[Strict]]
的是函数对象的内部插槽.这是否意味着:
// Non-strict surrounding code
{
function foo() {"use strict";}
}
Run Code Online (Sandbox Code Playgroud)
应该被认为是上表中的"严格模式"?然而,这与我最初的直觉相矛盾.
请记住,无论实际的实现不一致,我对ES6规范本身最感兴趣.
Ber*_*rgi 27
据我所知,
strict
指[[Strict]]
的是函数对象的内部插槽.
没有.是的.它指的是函数(的严格性或脚本),其中包含该函数声明的块发生.不是要声明(或不是)声明的函数的严格性.
"web扩展"仅适用于草率(非严格)代码,并且仅当函数语句的外观是"理智"时 - 例如,如果其名称不与形式参数或词法冲突声明变量.
请注意,没有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
Run Code Online (Sandbox Code Playgroud)
1:见下文.要求警告.
2:通常情况下,a SyntaxError
抛出
3:ES5.1§12中的注释说明了" 实现之间的重大且不可调和的变化 "(例如这些).建议使用警告.
那么现在具有Web兼容性的ES6实现如何在具有遗留语义的草率模式函数中的块中进行函数声明?
首先,纯语义仍然适用.也就是说,函数声明被提升到词块的顶部.
但是,还有一个var
声明被提升到封闭函数的顶部.
并且当评估函数声明时(在块中,就像它像声明一样),将函数对象分配给该函数范围的变量.
这可以通过代码更好地解释:
function enclosing(…) {
…
{
…
function compat(…) { … }
…
}
…
}
Run Code Online (Sandbox Code Playgroud)
与...一样的工作
function enclosing(…) {
var compat? = undefined; // function-scoped
…
{
let compat? = function compat(…) { … }; // block-scoped
…
compat? = compat?;
…
}
…
}
Run Code Online (Sandbox Code Playgroud)
是的,这有点令人困惑,有两个不同的绑定(用下标0和1表示)具有相同的名称.所以现在我可以简洁地回答你的问题:
在街区之外可见?
是的,就像一个var
.但是,第二个绑定仅在块内可见.
悬挂?
是的 - 两次.
到了哪一点?
两者都是函数(无论是初始化的undefined
)和块(用函数对象初始化).
"TDZ"?
不是在引用引用的词法声明变量(let
/ const
/ class
)的临时死区的意义上,不是.但是在执行body之前遇到函数声明之前,函数范围的变量undefined
(特别是在块之前),如果你试图调用它,你也会得到一个异常.