javascript - JavaScript 中 for-body 的运行时语义
问题描述
在规范中,JavaScript 中 for-body 评估的运行时语义是:
运行以下代码时,我希望创建两个函数对象,每个 for-body 迭代一个。
for(let x = 0; x < 2; x++) {
function f() {}
}
这是否包含在 4.b. 中?在上面的规范片段中?
解决方案
是的,确实是EcmaScript 2015 规范的第 13.7.4.8 节,第 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指出:
函数可以有条件地声明,也就是说,一个函数语句可以嵌套在一个
if
语句中,但是结果在不同的实现中是不一致的,因此这种模式不应该在生产代码中使用。对于条件函数创建,请改用函数表达式。
这句话也适用于循环结构,因为它们也有条件地执行。因此,使用函数表达式可以获得更可靠的结果:
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
在循环完成后可以访问。
推荐阅读
- django - Django 过滤器 ModelMultipleChoiceFilter: __init__() 至少需要 2 个参数(给定 3 个)
- amazon-web-services - 每 11 秒运行一次代码
- python-3.x - Azure Put Blob API 返回规范化标头中的文件大小不匹配
- java - 在运行时检查 --module-path 值
- html - Nav、Subnav 和 Sidenav 已修复,而正文滚动
- odoo-10 - 如何正确继承odoo中的继承视图?
- c# - 尝试使用 c# asp.net 后面的代码将超链接分配到 PDF 内的 pdf 位置
- java - 从 java 应用程序备份 MySQL 数据库
- javascript - 反应未定义的地图输出
- php - 使用参数流明重定向