Entries

スポンサーサイト

カテゴリ:スポンサー広告
更新日:--------
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

やっとわかったクロージャー。なんだ、スコープの問題だけじゃん。

カテゴリ:JavaScript
更新日:2012-09-06
JavaScriptを本格的に使い始めた頃、聞きなれない言葉が目につくようになった。無名関数とクロージャーである。

無名関数は、まぁ、簡単。名前がない関数、ってそのまま。使い方も、jQueryのサンプルを見てれば分かった。

問題は、クロージャー。

> [JavaScript] 猿でもわかるクロージャ超入門 まとめ - DQNEO起業日記

いやぁ、力作だと思うんだよ。だけど、ごめん。かえって分からなくなった。で、まぁいいや、と思って、ほっておいたんだけど・・・

だいたいさぁ。呼び出すたびにカウントアップする関数なんてサンプルがいけないと思う。

> クロージャ - Wikipedia
function newCounter() {
var i = 0;
return function() { // 無名関数
i = i + 1;
return i;
}
}

c1 = newCounter();
alert(c1()); // 1
alert(c1()); // 2
alert(c1()); // 3
alert(c1()); // 4
alert(c1()); // 5
Wikipediaにも載っている定番のサンプル。クロージャーの説明といえば、ほとんど、これ。でもさ。これが何の役に立つの?これができると何が嬉しいの?

カウントアップする関数なんて、クロージャーなんて考えなくても、別に難しいことじゃない。
var i = 0;
function countUp() {
i = i + 1;
return i;
}
これだけのことじゃん?

え?グローバル変数が良くない?
なら、囲えばいい。オブジェクト指向ならクラスで、構造化言語だってモジュール化すればいい。

JavaScriptでは、関数で囲えばスコープができる。というわけで、関数で囲う。
function () {
var i = 0;
function countUp() {
i = i + 1;
return i;
}
}
あれ、クロージャー?

まぁ、これだと外側の関数(エンクロージャー)の外側でcountUp関数が呼び出せないから、関数ポインタを何とかして取り出さないといけない。で、そのように書きなおせば、件のサンプルになる。

ようは関数で作ったスコープをクロージャーと呼んでるだけ。無名関数とか、関数を返す関数とかは、おまけみたいなものだ。

サンプルが簡単すぎると、動きは理解できても、応用できないんじゃないかなぁ。もっと使えるサンプルのほうがいいと思うんだけど。

ええと。例えば、ループの中で非同期呼び出して、コールバック関数でループ変数を使いたい場合。
for (i=0; i<max; i++) {
$.get(api, function(){
// ここで変数 i が使いたい
});
}
たぶん、ハマった人は多いと思うんだ。私もだけど。

非同期呼び出しのコールバックだから、実行されるときには、たいていループ処理は終わってる。で、変数 i の値は、だいたい最大値になってる。つまり、すべて同じ値。ループ変数を使いたいくらいなんだから、呼び出しの順番を知りたいんだよね。それが同じ値じゃ、意味が無い。

JavsScriptを使い始めた当初は、どうすればいいのか分からなくて、非同期関数を呼び出す前にDOM要素にデータ属性なんかを使って書き込んでたりした。でも、ある時、即時関数というのを知った。
for (i=0; i<max; i++) {
(function(i){
$.get(api, function(){
// ここで変数 i が使いたい
});
}(i));
}
これで、ループ変数 i が束縛されるのでコールバック関数の中でも使えるようになる。で、これがクロージャーというわけだ。

たぶん、クロージャーと意識しなくても使ってると思うんだよね。だけど、プログラミング言語の勉強って、言葉が優先で使い方がよくわからない、ってことが多いような気がする。
スポンサーサイト

Appendix

プロフィール

いむら@fintopo いむら@fintopo

ガーデニングが趣味のフリーのシステムエンジニア兼プログラマ(フルスタックエンジニア)です。

仕事募集中です。個人なので、融通がききます。 大規模な開発はできないかもしれませんが、研究や製品開発レベルでの小規模開発、特に相談しながら新しいものを作っていくのが得意です。詳しくはWebサイトをご覧ください。
詳しくは「fintopoとは」をご覧ください。

> fintopoとは

このページのQRコード

季節暦

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。