APIでは、意識してクロージャーを使う機会が多い。多数のマーカーに対して、ループ回して処理を行う際などに使うのだが、ちょっと躓いたのでメモ。以下のようなjavascriptのコードを考えてみる。3;i++){numbers.push(function(){alert(i);});}numbers[0]();numbers[1]();numbers[2]();何となく、numbers配列にpushされる無名関数内のiには、ループカウンタiの、実行時の値が束縛されると思い込んでいた。このコードを実行すると「0」「1」「2」と表示されると。実際には3回とも「3」が表示される。これは、javascriptのループでクロージャーを使う際に間違えやすい例として有名な話らしく、ググるといっぱい出てくる。*1結局、無名関数中のiは、ループカウンタであるiが「コピー」されるのではなく、ループカウンタであるiへの「参照」ということらしい。ループ完了時のiの値「3」が表示されてしまう。ちなみに、正しく動かすには以下のようにしてやればよい。一段関数スコープで括ってやり、ループカウンタであるiを引数として渡すことで、numにiの値を束縛することができる。3;i++){(function(num){numbers.push(function(){alert(num);});})(i);}numbers[0]();numbers[1]();numbers[2]();ちなみにPerlではちなみにPerlのforでは、ループごとにスコープ(新しい環境)が作られるという記載があったので、試してみた。};push(@numbers,$obj);}$numbers[0]->{func}();$numbers[1]->{func}();$numbers[2]->{func}();実行結果:012お~、確かに0,1,2が表示されるね!と思ったのだけど、以下のコードだとなぜか結果がすべて3になる。};push(@numbers,$obj);}$numbers[0]->{func}();$numbers[1]->{func}();$numbers[2]->{func}();実行結果:333ループの書き方によって、新しい環境ができる/できないがあるみたい。pythonではpythonでの実行結果は、以下のとおり。結果はすべて「2」になるが、基本的にjavascriptと一緒。"\n")))numbers[0]()numbers[1]()numbers[2]()実行結果:222なので、(javascriptの例にあわせて)こんなことしてやれば、想定どおりの動きになるかな。コメントをキャンセルメールアドレスが公開されることはありません。ThemeHall.。