【JavaScript】即時関数とthis

  • このエントリーをはてなブックマークに追加

IIFEは定義されるとすぐに実行される。
即時関数の中のthisにはグローバルオブジェクトがセットされることに注意する。
次にような挙動になる。
bind、apply、callを使ってthisの値をコントロールする。


var value = "GlobalRed",
    ob = {};
ob.value = "blue";

ob.abc = function() {
    console.log("1:this.value=" + this.value);
};

ob.abc(); //blue

var ob2 = ob.abc;

//この時、thisがグローバルオブジェクトであることに注意する。
ob2(); //GlobalRed

const ob3 = ob2.bind(ob);

ob3(); //blue

const ob4 = ob.abc.bind(ob);

ob4(); //blue


//即時実行関数式(Immediately-invoked function expression : IIFE)
ob.abc2 = (function() {
    console.log("2:this.value=" + this.value); //GlobalRed
})();

//対処方法 その1
//callメソッドを使う
ob.abc3 = (function() {
    console.log("3:this.value=" + this.value); //blue
}).call(ob);

//対処方法 その2 
//applyメソッドを使う
ob.abc4 = (function() {
    console.log("4:this.value=" + this.value); //blue
}).apply(ob);

//対処方法 その3
//thisでなくobオブジェクトを使う
ob.abc5 = (function() {
    console.log("5:ob.value=" + ob.value); //blue
})();

//即時関数とクロージャとthis(その1)
ob.abc6 = (function() {

    var that = {};
    that.value = "black";
    //thisにはグローバルオブジェクトがセットされている
    console.log("6-1:this.value=" + this.value); //GlobalRed

    that.a1 = function() {
        console.log("6-2:this.value=" + this.value); //black
    };

    return that;

})();

ob.abc6.a1();

//即時関数とクロージャとthis(その2)
ob.abc7 = (function() {
    //thisにはグローバルオブジェクトがセットされている
    //これはやってはダメなパターン
    var that = this;
    that.value = "black";
    //これはグローバルなa1関数を定義していることになる。
    //グローバル関数を定義しないためにクロージャを使用しているのに
    //グローバル関数を定義してはダメ。
    that.a1 = function() {
        console.log("7:this.value=" + this.value); //black
    };

    return that;

})();

a1(); //GlobalRed
//即時関数とクロージャとthis(その3)
ob.abc8 = (function() {

    var that = {};
    that.value = "black";

    console.log("8-1:this.value=" + this.value); //blue

    //bindで
    that.a1 = function() {
        console.log("8-2:this.value=" + this.value); //blue
    }.bind(this);

    return that;

}).apply(ob);

ob.abc8.a1(); //blue

//即時関数の中にstrictモードを使った場合(1)
ob.abc9 = (function() {
    "use strict";
    var that = {};
    that.value = "black";
    console.log("9-1:this=" + this); //undefined

    that.a1 = function() {
        console.log("9-2:this.value=" + this.value); //black
    };

    return that;

})();

ob.abc9.a1();

//即時関数の中にstrictモードを使った場合(2)
ob.abc10 = (function() {
    "use strict";
    var that = {};
    that.value = "black";
    console.log("10-1:this.value=" + this.value); //blue

    that.a1 = function() {
        console.log("10-2:this.value=" + this.value); //blue
    }.bind(this);

    return that;

}).apply(ob);

ob.abc10.a1();

/*

1:this.value=blue
1:this.value=GlobalRed
1:this.value=blue
2:this.value=GlobalRed
3:this.value=blue
4:this.value=blue
5:ob.value=blue
6-1:this.value=GlobalRed
6-2:this.value=black
7:this.value=black
8-1:this.value=blue
8-2:this.value=blue
9-1:this=undefined
9-2:this.value=black
10-1:this.value=blue
10-2:this.value=blue

*/



「即時関数」という呼び方は、O’Reilly Japan – JavaScriptパターン (oreilly.co.jp) ExternalLink に掲載されていた。
「即時呼び出し関数式」という呼び方は、O’Reilly Japan – JavaScriptデザインパターン (oreilly.co.jp) ExternalLink に掲載されていた。



  • このエントリーをはてなブックマークに追加

SNSでもご購読できます。

コメントを残す

*