今回はクロージャを使っている中で少し躓いたことを綴ります。
クロージャとは、関数の中に関数が入っている状態のことを指し、スコープ内の変数を関数に渡したい時によく使われます。
javascripterにとっては基本中の基本ですが、恥ずかしいことに下のような間違いを犯してしまい手こずる羽目に・・・。
</pre> document.body.onload = addElement; var json = { ハンバーグ: { 分類: '今日はハンバーグを食べました。ボリューム満点!', 主成分: 'タンパク質' }, カレー: { 分類: '暑い夏には激辛カレーが一番!', 主成分: '炭水化物' }, 親子丼: { 分類: 'ふわふわトロトロ懐かしの味!', 主成分: 'タンパク質' } }; function addElement () { for (var item in json) { // 新しい div 要素を作成します var newDiv = document.createElement("div"); // いくつかの内容を与えます var newContent = document.createTextNode(json[item]['分類']); newDiv.addEventListener('click', function() { sample (json[item]['主成分']); }, false); // テキストノードを新規作成した div に追加します newDiv.appendChild(newContent); // DOM に新しく作られた要素とその内容を追加します var currentDiv = document.getElementById("div1"); document.body.insertBefore(newDiv, currentDiv); } } function sample (e) { var component = e; console.log(component); } <pre>
addEventListenerの中の関数にjsonの要素を指定しています。本来ならば順に「タンパク質」「炭水化物」「タンパク質」と
出したかったのですが、生成されたdivの中身をクリックすると全ての要素に一番最後の「主成分」要素である「タンパク質」
が格納されてしまっています。
これは、格納しようとした値が保持できないために起きる事故です。
この場合は即時関数で実引数にjson要素を持たせればちゃんと値を保持したまま回ってくれます。
もっと沼るかと思いましたが即時関数のことを知っていたのでさくっと直すことが出来ました。
正しくはこんな感じです↓
</pre> (function(n) { newDiv.addEventListener('click', function() { sample (n); }, false); })(json[item]['主成分']); <pre>
reactをやっている限りはまあ使うことはないと思いますが(mapがありますしね)生のjavascriptを触るうえで覚えておくと
クロージャと即時関数まとめて理解できるので損はないと思います~。