Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/apache-flex/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript ES6中块级函数的精确语义是什么?_Javascript_Ecmascript 6_Language Lawyer - Fatal编程技术网

Javascript ES6中块级函数的精确语义是什么?

Javascript ES6中块级函数的精确语义是什么?,javascript,ecmascript-6,language-lawyer,Javascript,Ecmascript 6,Language Lawyer,我试图通过阅读原始规范来了解ES6中新的标准化块级函数。我的肤浅理解是: ES6中允许块级函数声明 他们吊到了楼顶 在严格模式下,它们在包含块外不可见 然而,由于这些语义中的一部分被指定为“可选”且仅对web浏览器()是强制性的,因此这一点更加复杂。因此,我希望填写下表: | Visible outside of block? | Hoisted? Up to which point? | "TDZ"? | ------------------------------------

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

  • ES6中允许块级函数声明
  • 他们吊到了楼顶
  • 在严格模式下,它们在包含块外不可见
然而,由于这些语义中的一部分被指定为“可选”且仅对web浏览器()是强制性的,因此这一点更加复杂。因此,我希望填写下表:

| 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" | | | | 但是,据我所知,
strict
指的是函数对象的
[[strict]]
内部插槽。这是否意味着:

// Non-strict surrounding code

{
    function foo() {"use strict";}
}
在上表中是否应被视为“严格模式”?然而,这与我最初的直觉相矛盾


请记住,我最感兴趣的是ES6规范本身,而不是实际的实现不一致。

我不知道您的困惑来自何方。根据这项研究,很清楚什么是或不是“严格模式”。在您的示例中,
foo
s
[[Strict]]
内部插槽实际上是
true
并且将处于严格模式,但承载它的块不会。第一句话(您引用的那句话)与托管块有关,而不是其中生成的内容。片段中的块不是严格模式,因此该部分应用于它

在我看来,
strict
指的是函数对象的
[[strict]]
内部插槽

不,是的。它确实涉及函数()的严格性,其中包含函数声明的块出现。不符合(或不)要声明的函数的严格性

“web扩展”只适用于草率的(非严格的)代码,并且只适用于函数语句的外观为“sane”的情况——例如,如果其名称与形式参数或词汇声明的变量不冲突

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

所以我们基本上有

| web compat pure
-----------------+---------------------------------------------
严格模式ES6 |块吊装块吊装
马虎模式ES6 |这是一个复杂的模块吊装
严格模式ES5 |未定义行为²语法错误
松散模式ES5 |未定义行为³合成错误
1:见下文。需要警告。
2:通常会抛出一个
SyntaxError
3:注释中提到“实现之间的重大且不可调和的变化”(例如)。建议发出警告

那么,对于具有传统语义的松散模式函数中的块中的函数声明,具有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
。但是,第二个绑定仅在块内部可见

吊装

是的,两次

到哪一点

函数(但使用未定义的
初始化)和块(使用函数对象初始化)

“TDZ”

不是在词汇声明变量(
let
/
const
/
class
)引发引用的时间死区的意义上,不是。但是在执行主体时遇到函数声明之前,函数范围的变量是
未定义的
(尤其是在块之前),如果你试图调用它,你也会得到一个异常



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

请忘记术语“提升”。在执行任何代码之前,都会处理所有函数声明。块级作用域影响标识符解析的发生方式(即与“提升”无关),块内声明的函数可能在块外可用,也可能在块外不可用。哦,函数声明是在变量声明之后处理的,所以它们会覆盖变量(当然,稍后对变量的赋值会改变这一点…。你确定吗?我认为B3.3中的strict指的是之前在中的算法描述中引入的局部变量。在这个算法中,
strict==func。[[strict]]
@rvid我真的不明白你的逻辑。考虑这个<代码> {var f,iStase= ISTraceTime();如果(.IS严格){f=函数()){使用“严格”}}}<代码>。现在,假设
IsInStrict
“起作用”(这里有一些关于如何测试它的建议),如果不是在严格模式下,那么进入if语句的逻辑将把外部范围转换为严格模式。这不符合逻辑,事实上造成了一个悖论。@rvidal-让我们再试一次:)。附录B是关于不属于本标准一部分的传统特性。列出它们是为了描述非标准的行为,但为了保持与旧代码的兼容性,这些行为是必需的。
function enclosing(…) {
    var compat₀ = undefined; // function-scoped
    …
    {
         let compat₁ = function compat(…) { … }; // block-scoped
         …
         compat₀ = compat₁;
         …
    }
    …
}