回答編集履歴
5
歯がゆい思いをする経験
    
        answer	
    CHANGED
    
    | 
         @@ -27,7 +27,7 @@ 
     | 
|
| 
       27 
27 
     | 
    
         | 
| 
       28 
28 
     | 
    
         
             
            それはおそらく、今までの murabito さんはコードが完成した時点で満足してしまい、「完成したコードの改善点」や「別の書き方がないか試行錯誤する事」を怠っていたからだと思います。
         
     | 
| 
       29 
29 
     | 
    
         
             
            一つの書き方しか知らないのでしたら、別の書き方を覚える必要もありませんが、複数の選択肢がなければ「最良のコード」を掴む事も出来ません。
         
     | 
| 
       30 
     | 
    
         
            -
            もし、今までに「現在は出来ないけど、こんなことが出来たらいいのに!」と 
     | 
| 
      
 30 
     | 
    
         
            +
            もし、今までに「現在は出来ないけど、こんなことが出来たらいいのに!」と歯がゆい思いをする経験があれば、新しい機能を知った時に「これがあれば、今までできなかった~が出来るぞ」な着想が容易になります。
         
     | 
| 
       31 
31 
     | 
    
         
             
            ある要件をコード化する場合に、一つのコードで満足せず、様々なパターンのコードを考え、それぞれの性質を理解するようにしてみて下さい。
         
     | 
| 
       32 
32 
     | 
    
         
             
            そうすることで、様々なAPIの利点/欠点を見て取れるようになります。
         
     | 
| 
       33 
33 
     | 
    
         | 
| 
         @@ -68,7 +68,7 @@ 
     | 
|
| 
       68 
68 
     | 
    
         
             
            ### 更新履歴
         
     | 
| 
       69 
69 
     | 
    
         | 
| 
       70 
70 
     | 
    
         
             
            - 2018/04/16 0:48 [JavaScript] オブジェクト, Map, WeakMap の使い分け方.md ->「スコープを分割する」節を「key 単位でスコープを分割する」にリネームし、「WeakMap 単位でスコープを分割する」と「オブジェクトの「参照不可能なプロパティ」のように扱う」節を追加
         
     | 
| 
       71 
     | 
    
         
            -
            - 2018/04/16  
     | 
| 
      
 71 
     | 
    
         
            +
            - 2018/04/16 01:07「Map と WeakMap は発想が逆のイメージ」節を追記
         
     | 
| 
       72 
72 
     | 
    
         
             
            - 2018/04/16 23:07 「key をオブジェクトにする意味」節を追記
         
     | 
| 
       73 
73 
     | 
    
         | 
| 
       74 
74 
     | 
    
         
             
            Re: murabito さん
         
     | 
4
「key をオブジェクトにする意味」節を追記
    
        answer	
    CHANGED
    
    | 
         @@ -21,9 +21,54 @@ 
     | 
|
| 
       21 
21 
     | 
    
         | 
| 
       22 
22 
     | 
    
         
             
            ただし、[key 単位でスコープを分割する](https://gist.github.com/think49/31a2cedb5c653fd18086ade669c04323#key-%E5%8D%98%E4%BD%8D%E3%81%A7%E3%82%B9%E3%82%B3%E3%83%BC%E3%83%97%E3%82%92%E5%88%86%E5%89%B2%E3%81%99%E3%82%8B)は `wm[object] = value` のイメージで書いているので、コードの書き方に依存する部分はあります。
         
     | 
| 
       23 
23 
     | 
    
         | 
| 
      
 24 
     | 
    
         
            +
            ### key をオブジェクトにする意味
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
            > 普通のオブジェクトはキーといったら文字列ですし、それにずっと慣れていたので、キーをオブジェクトにする意味がよく分かりません。
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
            それはおそらく、今までの murabito さんはコードが完成した時点で満足してしまい、「完成したコードの改善点」や「別の書き方がないか試行錯誤する事」を怠っていたからだと思います。
         
     | 
| 
      
 29 
     | 
    
         
            +
            一つの書き方しか知らないのでしたら、別の書き方を覚える必要もありませんが、複数の選択肢がなければ「最良のコード」を掴む事も出来ません。
         
     | 
| 
      
 30 
     | 
    
         
            +
            もし、今までに「現在は出来ないけど、こんなことが出来たらいいのに!」と熱望するような経験があれば、新しい機能を知った時に「これがあれば、今までできなかった~が出来るぞ」な着想が容易になります。
         
     | 
| 
      
 31 
     | 
    
         
            +
            ある要件をコード化する場合に、一つのコードで満足せず、様々なパターンのコードを考え、それぞれの性質を理解するようにしてみて下さい。
         
     | 
| 
      
 32 
     | 
    
         
            +
            そうすることで、様々なAPIの利点/欠点を見て取れるようになります。
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
            オブジェクトは [key, value] の集合体ですが、key はString型に限定されています(Symbol 型もありますが、説明上、ここでは除外します)。
         
     | 
| 
      
 35 
     | 
    
         
            +
            例えば、key を使用して四則演算するコードがあり、`+` で和算を試みた場合、単純に指定すると**文字列連結**として扱われてしまうので、予め、Number 型に変換しておく必要があります。
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
            ```JavaScript
         
     | 
| 
      
 38 
     | 
    
         
            +
            var key = '1';
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
            console.log(1 + key);         // "11"
         
     | 
| 
      
 41 
     | 
    
         
            +
            console.log(1 + Number(key)); // 2
         
     | 
| 
      
 42 
     | 
    
         
            +
            ```
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
            対して、Map は Number 型を key に指定可能なので、型変換処理が不要です。便利ですね。
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
            では、Object 型を指定するメリットは何なのか。
         
     | 
| 
      
 47 
     | 
    
         
            +
            DOMノードにデータを埋め込みたいと思ったことはありませんか。
         
     | 
| 
      
 48 
     | 
    
         
            +
            要素ノードならば、`data-*` 属性がありますが、これは String 型に限定されています。
         
     | 
| 
      
 49 
     | 
    
         
            +
            WeakMap を使用すれば、要素ノードに任意の値を結びつけることが可能です。
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
            ```JavaScript
         
     | 
| 
      
 52 
     | 
    
         
            +
            var element = document.getElementById('sample'),
         
     | 
| 
      
 53 
     | 
    
         
            +
                wm = new WeakMap([[element, 'Hello, World!']]);
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
            console.log(wm.get(element)); // "Hello, World!"
         
     | 
| 
      
 56 
     | 
    
         
            +
            ```
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
            今まで、これと同等のコードを書くには、二次元配列を検索する必要がありました。
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
            ```JavaScript
         
     | 
| 
      
 61 
     | 
    
         
            +
            var mapLike = [[element1, 'Hello, World!'], [element2, 'Hello, JavaScript!'], [element3, 'Hello, ECMAScript!']];
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
            console.log(mapLike.find(array => target === array[0])[1]);
         
     | 
| 
      
 64 
     | 
    
         
            +
            ```
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
            WeakMapはこのコードよりシンプルですし、弱参照なのですから、使わない理由はありません。
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
       24 
68 
     | 
    
         
             
            ### 更新履歴
         
     | 
| 
       25 
69 
     | 
    
         | 
| 
       26 
70 
     | 
    
         
             
            - 2018/04/16 0:48 [JavaScript] オブジェクト, Map, WeakMap の使い分け方.md ->「スコープを分割する」節を「key 単位でスコープを分割する」にリネームし、「WeakMap 単位でスコープを分割する」と「オブジェクトの「参照不可能なプロパティ」のように扱う」節を追加
         
     | 
| 
       27 
71 
     | 
    
         
             
            - 2018/04/16 1:07「Map と WeakMap は発想が逆のイメージ」節を追記
         
     | 
| 
      
 72 
     | 
    
         
            +
            - 2018/04/16 23:07 「key をオブジェクトにする意味」節を追記
         
     | 
| 
       28 
73 
     | 
    
         | 
| 
       29 
74 
     | 
    
         
             
            Re: murabito さん
         
     | 
3
key 単位でスコープを分割する
    
        answer	
    CHANGED
    
    | 
         @@ -12,12 +12,15 @@ 
     | 
|
| 
       12 
12 
     | 
    
         
             
            ```JavaScript
         
     | 
| 
       13 
13 
     | 
    
         
             
            var wm = new WeakMap([[object, value]]);  // こういうコードを書いた場合
         
     | 
| 
       14 
14 
     | 
    
         | 
| 
       15 
     | 
    
         
            -
            wm[object] = value;  // 実際の挙動イメージはこちらが正しい 
     | 
| 
      
 15 
     | 
    
         
            +
            wm[object] = value;  // 実際の挙動イメージはこちらが正しいが
         
     | 
| 
       16 
16 
     | 
    
         
             
            object[wm] = value;  // 弱参照のイメージ的にはこちらの方がしっくりくる
         
     | 
| 
       17 
17 
     | 
    
         
             
            ```
         
     | 
| 
       18 
18 
     | 
    
         | 
| 
       19 
19 
     | 
    
         
             
            なぜなら、object の参照が切れると、WeakMap 側の参照も切れる感覚が下段コードの方がイメージしやすいからです。
         
     | 
| 
      
 20 
     | 
    
         
            +
            [WeakMap 単位でスコープを分割する](https://gist.github.com/think49/31a2cedb5c653fd18086ade669c04323#weakmap-%E5%8D%98%E4%BD%8D%E3%81%A7%E3%82%B9%E3%82%B3%E3%83%BC%E3%83%97%E3%82%92%E5%88%86%E5%89%B2%E3%81%99%E3%82%8B)と[オブジェクトの「参照不可能なプロパティ」のように扱う](https://gist.github.com/think49/31a2cedb5c653fd18086ade669c04323#%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%81%AE%E5%8F%82%E7%85%A7%E4%B8%8D%E5%8F%AF%E8%83%BD%E3%81%AA%E3%83%97%E3%83%AD%E3%83%91%E3%83%86%E3%82%A3%E3%81%AE%E3%82%88%E3%81%86%E3%81%AB%E6%89%B1%E3%81%86)はそのイメージで書いています。
         
     | 
| 
       20 
21 
     | 
    
         | 
| 
      
 22 
     | 
    
         
            +
            ただし、[key 単位でスコープを分割する](https://gist.github.com/think49/31a2cedb5c653fd18086ade669c04323#key-%E5%8D%98%E4%BD%8D%E3%81%A7%E3%82%B9%E3%82%B3%E3%83%BC%E3%83%97%E3%82%92%E5%88%86%E5%89%B2%E3%81%99%E3%82%8B)は `wm[object] = value` のイメージで書いているので、コードの書き方に依存する部分はあります。
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
       21 
24 
     | 
    
         
             
            ### 更新履歴
         
     | 
| 
       22 
25 
     | 
    
         | 
| 
       23 
26 
     | 
    
         
             
            - 2018/04/16 0:48 [JavaScript] オブジェクト, Map, WeakMap の使い分け方.md ->「スコープを分割する」節を「key 単位でスコープを分割する」にリネームし、「WeakMap 単位でスコープを分割する」と「オブジェクトの「参照不可能なプロパティ」のように扱う」節を追加
         
     | 
2
「Map と WeakMap は発想が逆のイメージ」節を追記
    
        answer	
    CHANGED
    
    | 
         @@ -4,8 +4,23 @@ 
     | 
|
| 
       4 
4 
     | 
    
         | 
| 
       5 
5 
     | 
    
         
             
            - [[JavaScript] オブジェクト, Map, WeakMap の使い分け方.md](https://gist.github.com/think49/31a2cedb5c653fd18086ade669c04323)
         
     | 
| 
       6 
6 
     | 
    
         | 
| 
      
 7 
     | 
    
         
            +
            ### Map と WeakMap は発想が逆のイメージ
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            私は WeakMap の発想の原点が `Node#setUserData` の代替APIとして認識していたところが大きいのですが、感覚的には Map とは逆に考える事が多い気がします。
         
     | 
| 
      
 10 
     | 
    
         
            +
            WeakMap はオブジェクトをキーにして値をセットするわけですが、感覚的には「オブジェクトに WeakMap の key を代入している」がしっくりきます。
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
            ```JavaScript
         
     | 
| 
      
 13 
     | 
    
         
            +
            var wm = new WeakMap([[object, value]]);  // こういうコードを書いた場合
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            wm[object] = value;  // 実際の挙動イメージはこちらが正しいですが
         
     | 
| 
      
 16 
     | 
    
         
            +
            object[wm] = value;  // 弱参照のイメージ的にはこちらの方がしっくりくる
         
     | 
| 
      
 17 
     | 
    
         
            +
            ```
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
            なぜなら、object の参照が切れると、WeakMap 側の参照も切れる感覚が下段コードの方がイメージしやすいからです。
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
       7 
21 
     | 
    
         
             
            ### 更新履歴
         
     | 
| 
       8 
22 
     | 
    
         | 
| 
       9 
     | 
    
         
            -
            - 2018/04/16 0:48 「スコープを分割する」節を「key 単位でスコープを分割する」にリネームし、「WeakMap 単位でスコープを分割する」と「オブジェクトの「参照不可能なプロパティ」のように扱う」節を追加
         
     | 
| 
      
 23 
     | 
    
         
            +
            - 2018/04/16 0:48 [JavaScript] オブジェクト, Map, WeakMap の使い分け方.md ->「スコープを分割する」節を「key 単位でスコープを分割する」にリネームし、「WeakMap 単位でスコープを分割する」と「オブジェクトの「参照不可能なプロパティ」のように扱う」節を追加
         
     | 
| 
      
 24 
     | 
    
         
            +
            - 2018/04/16 1:07「Map と WeakMap は発想が逆のイメージ」節を追記
         
     | 
| 
       10 
25 
     | 
    
         | 
| 
       11 
26 
     | 
    
         
             
            Re: murabito さん
         
     | 
1
スコープを分割する」節を「key 単位でスコープを分割する」にリネームし、「WeakMap 単位でスコープを分割する」と「オブジェクトの「参照不可能なプロパティ」のように扱う」節を追加
    
        answer	
    CHANGED
    
    | 
         @@ -1,5 +1,11 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            ### オブジェクト, Map, WeakMap の使い分け方
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
       1 
3 
     | 
    
         
             
            下記にまとめました。
         
     | 
| 
       2 
4 
     | 
    
         | 
| 
       3 
5 
     | 
    
         
             
            - [[JavaScript] オブジェクト, Map, WeakMap の使い分け方.md](https://gist.github.com/think49/31a2cedb5c653fd18086ade669c04323)
         
     | 
| 
       4 
6 
     | 
    
         | 
| 
      
 7 
     | 
    
         
            +
            ### 更新履歴
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            - 2018/04/16 0:48 「スコープを分割する」節を「key 単位でスコープを分割する」にリネームし、「WeakMap 単位でスコープを分割する」と「オブジェクトの「参照不可能なプロパティ」のように扱う」節を追加
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
       5 
11 
     | 
    
         
             
            Re: murabito さん
         
     |