gpt4 book ai didi

javascript - ES6 中 block 级函数的精确语义是什么?

转载 作者:行者123 更新时间:2023-11-30 06:14:11 25 4
gpt4 key购买 nike

我试图通过阅读原始规范来了解 ES6 中新的标准化 block 级函数。我粗浅的理解是:

  • block 级函数声明在 ES6 中是允许的。
  • 他们吊到街区的顶部。
  • 在严格模式下,它们在包含 block 之外是不可见的。

然而,由于这些语义的一部分被指定为“可选”并且仅对 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" |                             |                               |          |

Also it is unclear to me what "strict mode" means in this context. This distinction seems to be introduced in Annex B3.3, as part of some additional steps for the runtime execution of a function declaration:

1. If strict is false, then
...

但是,据我所知,strict 指的是函数对象的[[Strict]] 内部插槽。这是否意味着:

// 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.

没有。是的。它确实指的是函数的严格性 (or script)在其中包含函数声明的 block 出现。不是要声明(或不声明)的函数的严格性。

“网络扩展”仅适用于草率(非严格)代码,并且仅当函数语句的外观“合理”时——也就是说,例如,如果它的名称不与正式名称冲突参数或词法声明的变量。

请注意,在没有网络兼容性语义的情况下,严格代码和草率代码之间没有区别。在纯 ES6 中, block 中的函数声明只有一种行为。

所以我们基本上有

                 |      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 实现对于具有遗留语义的草率模式函数中的 block 中的函数声明表现如何?
首先,纯语义仍然适用。即函数声明被提升到词法 block 的顶部。
但是,还有一个 var 声明 被提升到封闭函数的顶部。
当函数声明被求值时(在 block 中,就好像它像语句一样被满足),函数对象被分配给那个函数范围的变量。

这可以用代码更好地解释:

function enclosing(…) {

{

function compat(…) { … }

}

}

工作方式与

相同
function enclosing(…) {
var compat₀ = undefined; // function-scoped

{
let compat₁ = function compat(…) { … }; // block-scoped

compat₀ = compat₁;

}

}

是的,这有点令人困惑,因为有两个不同的绑定(bind)(用下标 0 和 1 表示)具有相同的名称。所以现在我可以简洁地回答你的问题:

Visible outside of block?

是的,就像一个var。但是,还有第二个绑定(bind)仅在 block 内可见。

Hoisted?

是的 - 两次。

Up to which point?

函数(用 undefined 初始化)和 block (用函数对象初始化)。

"TDZ"?

不是在词法声明的变量(let/const/class)的时间死区的意义上抛出引用,不。但是在body的执行中遇到函数声明之前,函数作用域的变量是undefined(特别是在block之前),如果你试图调用它也会得到一个异常.


仅供引用:在 ES6 中,上述行为仅针对函数作用域中的 block 指定。 Since ES7这同样适用于 eval 和全局范围内的 block 。

关于javascript - ES6 中 block 级函数的精确语义是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57235948/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com