【发布时间】:2018-02-28 12:58:58
【问题描述】:
在 for 循环中处理 let 和 const 时,我遇到了一些奇怪的结果。我的印象是用 let 或 const 定义的变量的范围仅限于它周围的括号。
因此,在 for 循环中,将为每个 let 和 const 定义一个新范围。但是,我在 for 循环中的一些变量在每次迭代中都带有作用域。奇怪的是,并不是所有的变量都在for循环中。
如果是所有这些,我猜我对 let 和 const 范围如何工作的假设是错误的。只有其中一些人携带的事实对我来说没有意义。
我在 Chrome 中运行它 - 版本 60.0.3112.113(官方构建)(64 位)
我已经削减了一些代码以使其更简洁,但请查找"// ***" 以查看我的变量范围没有意义的地方。
for (let i = 0; i < combinedRoles.length; i++)
{
// *** orgs, permObjArray, roleOrgTree, rolePanelId are all carrying scope
const orgs = $sidebar.data("org-tree");
const orgRole = combinedRoles[i];
const roleId = orgRole.roleId;
const permObjArray = orgRole.permObjsArray;
const rolePanelId = "#user-" + user.userId + "-role-" + roleId;
const $selectedRoleRow = $userPanel.find(".role-selection-row.selected");
let $roleSelection = $userPanel.find(rolePanelId);
$roleSelection.data("roleData", orgRole);
// *** roleOrgTree's scope is carrying over between "i" iterations
// *** So below when I set the data value for the html element from before.
let roleOrgTree = [];
roleOrgTree = orgs.map(function(org)
{
let stateObj = {checked : false, checkbox_disabled : false, selected : false};
org.a_attr = { "class" : "role-org-tree-anchor" };
org.li_attr = { "class" : "role-org-tree-li" }
currUserOrgPerms = org.anmUserRole.permissions;
if ($.inArray(roleId, org.availableRoleIds) < 0)
{
org.a_attr = { "class" : "role-org-tree-anchor disable-org-tree-anchor role-not-available" };
org.li_attr = { "class" : "role-org-tree-li disable-org-tree-node" }
stateObj.checkbox_disabled = true;
}
org.state = stateObj;
return org;
});
// *** What's happening is since roleOrgTree's scope is carrying over
// *** it is changing the previous element's data object
$roleSelection.data("roleOrgTree", roleOrgTree);
// *** However the scope is not carrying over for permissionsTree
// *** and each html element's data object is correct
let permissionsTree = [];
let familyTree = [];
// Creating the permissions tree for this role
//permObjArray.forEach(function(obj) {
permissionsTree = permObjArray.map(function(obj) {
const permFamily = obj.perm_family;
if (familyTree.indexOf(permFamily) < 0)
{
familyTree.push(permFamily);
const familyObj = {
id: permFamily,
text : permFamily,
parent : "#",
li_attr: { "class" : "disable-org-tree-node" },
a_attr : { "class" : "disable-org-tree-anchor hide-checkbox" }
};
permissionsTree.push(familyObj);
}
obj.state = {checked: true, selected: true, checkbox_disabled : true};
obj.li_attr = { "class" : "disable-org-tree-node" };
obj.a_attr = { "class" : "disable-org-tree-anchor" };
return obj;
});
// *** permissionsTree scope is not carrying over so the previous
// *** element's ($roleSelection) data object is not getting over written
$roleSelection.data("rolePermTree", permissionsTree);
};
从我的 chrome 开发人员工具中,您可以看到右侧的“范围”和 Block 变量已经具有范围但只是未定义。为什么会这样?
【问题讨论】:
-
很难理解您描述的问题。你能添加 HTML 并解释它应该做什么以及它正在做什么吗?
-
您正在修改保存在
$sidebar.data("org-tree")中的org对象。 -
它应该是复制模板 html div 以及用户可能拥有的每个角色。因此它将创建模板的克隆并将其放入 DOM 中,然后将一些对象存储在克隆模板的数据对象中以供以后访问。
-
@Barmar,map 函数没有创建新实例?如果是这样的话,为什么权限树也不能承载范围
-
这看起来不像minimal reproducible example。
标签: javascript scope ecmascript-6