LoginSignup
1
3

More than 5 years have passed since last update.

JavaScriptのクロージャについて少し調べた

Last updated at Posted at 2016-11-12

ある関数内で外のスコープの変数を使用する場合。

var message = "test";
var func = function(){
    alert(message);
};

func();     // test
message = "change";
func();     // change

funcを定義した後に変数の値を変更するとfuncの実行結果も変わる。

また、関数が定義されたスコープの外でその関数を実行する場合。

var func;
(function(){
    var message = "test";
    func = function(){
        alert(message);
    }
})();

alert(message);     // undefined or not defined
func();         // test
message = "change";
func();         // test

変数messageのスコープは7行目で終わっているはずだが
定義したfuncを使うことで値を取得できる。
ということは上のケースもこちらのケースも
関数内で使用した変数がどのスコープからでも参照できているということか。

調べてみるとこの概念をクロージャというらしい。
なるほど。JavaScriptにおけるクラス定義は
このクロージャという概念を使って定義されているわけだ。

ちなみに最初のケースで定義時の変数の値を使用したい場合はevalを使って定義するとできる。

var message = "test";
var func = eval("(function(){" + 
    "return function(){" +
        "alert(\"" + message + "\");" +
    "}" +
"})()");

func();     // test
message = "change";
func();     // test

文字列で書くとデバッグできなさそうだが、最近のブラウザなら
うまいことやってくれるのであんしん。

クラスでメンバーを定義するときのやりかたを思い出すと
クロージャの概念をうまく使ってevalを使わずにできそうだ。

var message = "test";
var func = (function(){
    this.msg = message;
    return function(){
        alert(this.msg);
    };
})();

func();     // test
message = "change";
func();     // test

デバッグは問題なくできるとはいえ、evalを使う方法だと可読性が落ちるので
こっちのほうがいいかな。

あ、でもfuncにcallやapplyでthisを渡したいときはダメだな。

thisを使わなくても普通に変数定義したらできた。

var message = "test";
var func = (function(){
    var msg = message;
    return function(){
        alert(msg);
    };
})();

func();     // test
message = "change";
func();     // test

あれ?クラスのメンバ変数ってthis省略できないんじゃなかったっけ?
クラス定義してるわけじゃないからいいのか?まあいいか。

あ、引数渡しでもいけるな。

var message = "test";
var func = (function(msg){
    return function(){
        alert(msg);
    };
})(message);

func();     // test
message = "change";
func();     // test

この辺のスコープの自由さがJavaScriptの自由さって感じがするね。

1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3