在 the specification ,JavaScript 中 for-body 求值的运行时语义是:
运行以下代码时,我希望创建两个函数对象,for-body 的每次迭代创建一个。
for(let x = 0; x < 2; x++) {
function f() {}
}
这是否包含在 4.b 中?在上面的规范片段中?
最佳答案
是的,确实section 13.7.4.8 of the EcmaScript 2015 specification ,第 4.b 点描述了对 for
循环的主体(语句,如 13.7.4.7 中标识)进行求值,在您的示例中这意味着该函数对象 f
已创建。
每次迭代都会发生这种情况(第 4 步)。
您可以按如下方式监视双重创建:
let set = new Set;
for(let x = 0; x < 2; x++) {
function f() {}
set.add(f);
}
console.log(set.size); // 2 in Chrome, Firefox and Edge
我在 Chrome、FireFox 和 Edge 中得到输出 2。有些报告 1 作为输出。这很可能是 JavaScript 引擎可能进行的优化。
在此背景下,mdn备注:
Functions can be conditionally declared, that is, a function statement can be nested within an
if
statement, however the results are inconsistent across implementations and therefore this pattern should not be used in production code. For conditional function creation, use function expressions instead.
此评论也适用于循环结构,因为它们也是有条件执行的。因此,使用函数表达式可以获得更可靠的结果:
let set = new Set;
for(let x = 0; x < 2; x++) {
var f = function f() {};
set.add(f);
}
console.log(set.size); // 2 in Chrome, Firefox and Edge
请注意,在这两个代码段中,f
的作用域并不在 for
主体内,而是在周围的作用域内。因此,f
在循环完成后即可访问。
关于javascript - JavaScript 中 for-body 的运行时语义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60415791/