title: ES6 Let Const Block Scope Is Carrying Over Inside For Loop For Some Variables
body: <p>I am experiencing some bizarre results when dealing with let and const inside a for loop. I was under the impressions that a variable defined with let or const has a scope limited to the brackets surrounding it. </p>
  
  <p>So in a for loop a new scope would be defined for each let and const. However some of my variables inside the for loop are carrying scope from each iteration. What's weird is that it is not all of the variables inside the for loop.</p>
  
  <p>If it were all of them I would guess that my assumption about how let and const scope worked was wrong. The fact that only some of them are carrying isn't making sense to me. </p>
  
  <p>I am running this in Chrome - Version 60.0.3112.113 (Official Build) (64-bit)</p>
  
  <p>I have cut down some of my code to make it more concise to follow but look for <code>"// ***"</code> to see where my variable's scopes aren't making sense. </p>
  
  <pre><code>    for (let i = 0; i &lt; 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) &lt; 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) &lt; 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);
      };
  </code></pre>
  
  <p>From my chrome developer tools you can see that on the right hand side under "Scope" and Block the variables already have a scope but are just undefined. Why would that be?</p>
  
  <p><a href="https://i.stack.imgur.com/6dOvT.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/6dOvT.png" alt="Screenshot"></a></p>