jsのクロージャについて、勉強したのでまとめてみる。入門者向け。
2015/09/02
##キーワード
- スコープ
- 関数の中の関数
- 状態を保持する関数
##クロージャとは?
わからないことがあったら、まずはWikipediaですよね。
関数閉包はプログラミング言語における関数オブジェクトの一種。引数以外の変数を実行時の環境ではなく、自身が定義された環境(静的スコープ)において解決することを特徴とする。 ...wikipediaより
???
何を言ってるのか、よくわからないですね。
気を取り直して、はてなキーワードを見てみます。
閉包。関数内に出現する自由変数(関数内で宣言されていない変数)の解決の際、実行時の環境ではなく、関数を定義した環境の変数を参照できるようなデータ構造。 ...Hatena Keywordより
・・・
わからない・・・
##つくってみよう
よくわからないので、とりあえず作ってみましょう。
数字をカウントアップする関数を作ってみます。
var num = 0;
function countup(){
return ++num;
}
// できた。動かしてみます。
console.log( countup() ); // => 1
console.log( countup() ); // => 2 うんいい感じ。
num = 0; // ←
console.log( countup() ); // => 1 あれれ。
カウントアップする関数なのに、途中で0に戻ってしまいました。
これではまずい。
##スコープを切ろう
変数のスコープを切って、上書きされないようにしましょう。
// var num = 0;
function countup(){
var num = 0; // ← 移動
return ++num;
}
// 動かしてみよう。
console.log( countup() ); // => 1
console.log( countup() ); // => 1 カウントアップしてない。
num = 0; // ←
console.log( countup() ); // => 1 スコープは切れてるけど。
できない。(そりゃそうだ)
スコープは切れてるけど、状態が保持されていない。
(毎回初期化されている)
##そこでクロージャ。
そこでクロージャですよ。
var countup = (function(){
var num = 0;
return function(){
return ++num;
};
})();
// 実行すると、
console.log( countup() ); // => 1
console.log( countup() ); // => 2 いいね
num = 0; // ←
console.log( countup() ); // => 3 おっ できてる。
できた。
ちゃんとカウントアップもされてて、スコープも切れていますね。
最初のコードと2番目のコードをくっつけた感じ?
##軽く解説
軽くコードの解説をすると、
var countup = (function(){
...
})();
全体としては、即時関数を実行しその返り値を変数countupに代入しています。
変数numはこの外側の関数(即時関数)の中で宣言されています。
そしてその即時関数の返り値が、
return function(){
return ++num;
}
関数になっている!
関数の中に関数がありますね。
変数countupには、この内側の関数が代入されることになります。
変数numはこの内側の関数の外で宣言されていますね。
##つまり、クロージャとは
このように、
(外側の)関数の中にnumが宣言されていることで、スコープが切れていて、
(内側の)関数の外にnumが宣言されていることで、状態が保持されている。
これこそがクロージャなのです!
var countup = (function(){
var num = 0;
return function(){ // 関数の中に関数がある
return ++num;
}
})();
console.log( countup() ); // => 1
console.log( countup() ); // => 2 ちゃんとカウントアップされてる(状態が保持されてる)
num = 0; // 上書きしようとしても
console.log( countup() ); // => 3 できない(スコープ切れてる)
##キーワードをもう一度
- スコープ
- 関数の中の関数
- 状態を保持する関数
##おわり
以上です。
ありがとうございました。
(実はQiita初投稿)
##参考
スライドver.
http://shuuuuun.github.io/study-closure/
ほぼおなじ。
Wikipedia
https://ja.wikipedia.org/wiki/%E3%82%AF%E3%83%AD%E3%83%BC%E3%82%B8%E3%83%A3
わからない。でも理解してから見るとちょっとわかる。
はてなキーワード
http://d.hatena.ne.jp/keyword/%A5%AF%A5%ED%A1%BC%A5%B8%A5%E3
わからない。でも理解してから見るとちょっとわかる。
猿でもわかるクロージャ超入門
http://dqn.sakusakutto.jp/2009/01/javascript_5.html
超わかりやすい。
うひょひょ
http://uhyohyo.net/javascript/9_5.html
わかりやすい。
JavaScriptでクロージャ入門(Qiita)
http://qiita.com/takeharu/items/4975031faf6f7baf077a
なるほど。
MDN
https://developer.mozilla.org/ja/docs/Web/JavaScript/Closures
ふむふむ。
クロージャを使ったプライベート関数の隠蔽について
http://satoshi.blogs.com/life/2007/12/javascript-2.html
なるほどなるほど。