ECMASCRIPT闭包-JavaScript中的求值块是什么?

ryoqjall  于 2023-01-29  发布在  Java
关注(0)|答案(1)|浏览(130)

https://tc39.es/ecma262/multipage/ecmascript-language-statements-and-declarations.html#sec-block-runtime-semantics-evaluation
14.2.2运行时语义评价
区块:{ }
1.返回空。
块:{语句列表}
1.让oldEnv成为正在运行的执行上下文的LexicalEnvironment。
1.设blockEnv为新声明环境(旧环境)。
1.执行块声明示例化(语句列表、块环境)。
1.将正在运行的执行上下文的LexicalEnvironment设置为blockEnv。
1.令blockValue为完成(StatementList的求值)。
1.将正在运行的执行上下文的LexicalEnvironment设置为oldEnv。
1.返回块值。
文档的这一部分是否涉及JavaScript何时“将焦点”放在新的执行上下文上(例如,当您开始执行一个函数时)?
这个问题是因为我正在学习闭包。

1szpjjfi

1szpjjfi1#

规范的这一部分描述了如何计算 * 块 *。
文档的这一部分是否涉及JavaScript何时"将焦点"放在新的执行上下文上...
不完全是,一个包含语句的块创建了一个新的声明性词法环境(步骤2),而不是一个新的执行上下文;然后,它将这个新的环境记录设置为正在运行的执行上下文的词法环境(步骤4)。块的声明性词法环境在那里包含块内的任何词法声明(即,使用letconstclass 1或-以复杂的方式-function 1,2的声明),因为在JavaScript中词法声明是块作用域的(尽管对于function声明来说,这很复杂),但是块不会创建新的执行上下文。
这个问题是因为我正在学习闭包。
这和闭包之间有一点关系,因为闭包会覆盖创建它的当前环境记录,所以如果你想知道在块中创建的闭包是否会覆盖块中的绑定:是的,是的。
1注意,我们在这里讨论的是class/function * 声明 *,而不是class/function * 表达式 *。由于class/function表达式不创建绑定 (不严格地说,是一个变量) 在它们出现的范围内,它们与本文的讨论无关。(回想一下,class/function * 声明 * 是class/function关键字出现在解析器期望语句的地方;如果它出现在应该是 * expression * 的位置,则它是class/function * expression *。示例:

function ex1() { }
// ^^^^^^^^^^^^^^^^^^−−−−−−−−−−−−−−−−−−−−−−−− function declaration

   export default function() { }
//                ^^^^^^^^^^^^^^−−−−−−−−−−−−− function declaration (yes, really; this is the only place where a name isn't required on a function declaration)

   const ex2 = function() { };
//             ^^^^^^^^^^^^^^−−−−−−−−−−−−−−−− function expression

   const ex2 = function name() { };
//             ^^^^^^^^^^^^^^^^^^^−−−−−−−−−−− function expression

   someArray.forEach((e) => console.log(e));
//                   ^^^^^^^^^^^^^^^^^^^^^−−− function expression

   class Ex4 { }
// ^^^^^^^^^^^^^−−−−−−−−−−−−−−−−−−−−−−−−−−−−− class declaration

   export default class { }
//                ^^^^^^^^^−−−−−−−−−−−−−−−−−− class declaration (yes, really)

   const Ex5 = class { };
//             ^^^^^^^^^−−−−−−−−−−−−−−−−−−−−− class expression

   const Ex6 = class Name { };
//             ^^^^^^^^^^^^^^−−−−−−−−−−−−−−−− class expression

   const Ex7 = register(class { });
//                      ^^^^^^^^^−−−−−−−−−−−− class expression

2关于function声明与块之间的复杂关系:最初,function声明创建var样式的函数作用域全局变量,并且在块中声明函数没有指定的行为(这是对规范的允许扩展,而且它们是由不同的JavaScript引擎[甚至不同版本之间的同一引擎]以不同的方式完成的)。规范的最新版本已经编纂了主要实现在块中的函数声明方面重叠的方式,它包含了一些块级语义,我在JavaScript: The New Toys的第3章中详细介绍了它,但实际上,一般来说,只是避免在块中声明函数(使用表达式代替);并非所有情况都具有指定的行为,并且 * 是 * 指定的行为可能是令人惊讶的。

相关问题