2017-09-19 9 views
1

forループ内でletとconstを扱うときに奇妙な結果が発生しています。私は、letまたはconstで定義された変数は、それを取り囲む括弧に限定されたスコープを持っているという印象を受けました。ES6 ConstブロックスコープでForループをいくつかの変数に渡しましょう

したがって、forループでは、letとconstごとに新しいスコープが定義されます。しかし、forループの中にある私の変数の中には、それぞれの繰り返しからスコープを持っているものがあります。奇妙なのは、forループ内のすべての変数ではないということです。

もし私がそれらのすべてであったとすれば、letとconstスコープの仕組みについての私の仮定は間違っていたと思います。それらのうちのいくつかだけが運んでいるという事実は、私には意味をなさない。

私はChromeでこれを実行しています - バージョン60.0.3112.113(公式ビルド)(64ビット)

私はより簡潔な場所を確認するために"// ***"ために従うが、探すために作るために私のコードの一部を削減しています私の変数のスコープは意味をなさない。私のChromeデベロッパーツールから

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); 
    }; 

あなたは「適用範囲」の下に右側にそれを見ることができ、ブロックは変数がすでにスコープを持っていますが、単に定義されていません。それはなぜでしょうか?

Screenshot

+0

あなたがそれを記述した方法で問題を理解するのは難しいです。 HTMLを追加して、それが何をするべきか、何をするのかを説明できますか? – Barmar

+0

'$ sidebar.data(" org-tree ")'に保存されている 'org'オブジェクトを変更しています。 – Barmar

+0

テンプレートのhtml divと、ユーザーが持つ可能性のあるロールごとにコピーされるはずです。したがって、テンプレートのクローンを作成してDOMに配置し、後でアクセスできるようにクローンテンプレートのデータオブジェクト内にいくつかのオブジェクトを格納します。 – shreddish

答えて

1

$sidebar.data("org-tree")は、データのクローンを作成しません、それは単にそれへの参照を返します。だから、後でorgsの上にマッピングして行うとき:あなたは要素のデータであるオブジェクトを変更している

org.a_attr = ...; 
org.li_attr = ...; 

、それがループの次の繰り返しに影響を与えます。

これらのオブジェクトは、変更する前にクローンする必要があります。

roleOrgTree = orgs.map(function(org) 
    { 
     org = Object.assign({}, 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; 
    }); 

ところで、あなたはすぐにorgs.map()からそれを再割り当てするつもりならroleOrgTree = []を初期化するにはポイントがありません。

+0

roleOrgTreeの初期化が必死だったので、何がスコープを運んでいたのか分かりませんでしたし、何かを試していました。 – shreddish

+0

これはうまくいきましたが、最初はマッピングの直後にroleOrgTreeの新しいインスタンスを作成しましたが、それも同様に機能しましたが、なぜスコープが実行されるのかわかりませんでした。このままでも、forループの最初の行でデバッガを一時停止すると、イベントは引き続き発生しますが、roleOrgTreeは次の繰り返しでも定義されます。まだ何かが欠けていますか? – shreddish

+0

これはデバッガアーティファクトのようです。コード内の変数にアクセスしようとすると、定義されません。 – Barmar

関連する問題