質問: 1` みたいなアクセス方法になります。 Closure に隠す理由には「開発者ツールで内部のデータ見るような人に見られたり編集されたくない」というのもあるようですが(ゲームとか?)、開発者ツールで WeakMap が見えるスコープのところに breakpoint 置いて REPL で操作できるので意味ないです。 というわけで、プロパティに直接置けば良いのでは?と思うのですがあまりそういうのを見ないように思います。 プロパティに置くことのデメリットや、普通にプロパティにおいてるけど問題ない、など意見もらえたら、と思います。
回答: ### WeakMap 要素ノードのプロパティに値を格納した場合、**将来的に同じ名前のプロパティが拡張された場合に衝突する危険性**があります。 `WeakMap` は要素ノードそのものを拡張するわけではないので、要素ノードにどんなプロパティが定義されても自由に設定できます。 > > Closure に隠す理由には「開発者ツールで内部のデータ見るような人に見られたり編集されたくない」というのもあるようですが(ゲームとか?)、開発者ツールで WeakMap が見えるスコープのところに breakpoint 置いて REPL で操作できるので意味ないです。 > > > `WeakMap` の使いどころはスコープを分割できることにあり、ユーザから値を隠す目的で使うものではないと思います。 例えば、 `` に対して a.js と b.js が別々の `WeakMap` を定義すれば、それぞれ独立したスコープで値を埋め込む事が出来ます。 **a.js で埋め込んだ WeakMap 値が b.js で埋め込んだ WeakMap 値と衝突する可能性はゼロ**です。 ### data-* 属性 プリミティブ値で良ければ、定義済みの `data-*` 属性を使う事も検討に値すると思います。 `WeakMap` とは逆にスコープが解放されているのが特徴で他の機能からも参照できるのでうまく使い分けると良いでしょう。 ### コード事例 * 要素ノードに複数の値を関連付ける - JSFiddle ``` 'use strict'; var mylibraryA = {name: 'A', value: 'foo', flag: true}, mylibraryB = {name: 'B', value: 'bar', flag: false}, map = new Map([['mylibraryA', mylibraryA], ['mylibraryB', mylibraryB]]), p; /** * property */ p = document.createElement('p'); map.forEach((object, name) => { for (let key of Object.keys(object)) { p[name + '-' + key] = object[key]; } }) console.log(JSON.stringify(Object.keys(p))); // ["mylibraryA-name", "mylibraryA-value", "mylibraryA-flag", "mylibraryB-name", "mylibraryB-value", "mylibraryB-flag"] /** * data-* attribute */ p = document.createElement('p'); map.forEach((object, name) => { for (let key of Object.keys(object)) { p.setAttribute('data-' + name + '-' + key, object[key]); } }) console.log(p.outerHTML); // /** * data-* attribute + JSON */ p = document.createElement('p'); map.forEach((object, name) => { p.setAttribute('data-' + name, JSON.stringify(object)); }) console.log(p.outerHTML); // /** * WeakMap */ p = document.createElement('p'); var wmapA = new WeakMap([[p, mylibraryA]]), wmapB = new WeakMap([[p, mylibraryB]]); console.log(JSON.stringify(wmapA.get(p))); // {name: "A", value: "foo", flag: true} console.log(JSON.stringify(wmapB.get(p))); // {name: "B", value: "bar", flag: false} ``` Re: lazex さん