はじめに
JavaScriptにはthisの値を変更できる3つのメソッドがある。call()、apply()、bind()である。それぞれ3つのメソッドについてメモ程度にまとめておく。
JavaScriptにおけるthis概要
JavaScriptにおけるthisの値は関数が実際に呼び出される際に設定される。つまり呼び出された場所によって、その値が変化する。
詳細はここで説明するよりも以下の記事が分かりやすい。
(https://qiita.com/mtoyopet/items/2fceef61b250e3917cb3)
(https://qiita.com/takkyun/items/c6e2f2cf25327299cf03)
call()メソッド概要
callはthisの値と引数を指定して関数を実行する。2つパラメータを渡す。
1つ目のパラメータには関数が実行される際のthisの値を渡す。
2つ目のパラメータには関数に渡す引数を渡す。
function callFrom(idNumber){
console.log(idNumber + ":" + this.name);
}
var person1={
name:"Tanaka"
};
var person2={
name:"Sato"
};
var name="Kudo";
callFrom.call(this,"global");
//=> global:Kudoと出力
callFrom.call(person1,"person1");
//=> person1:Tanakaと出力
callFrom.call(person2,"person2");
//=> person2:Satoと出力
1つ目のcallでは関数callFromが実行される際のthisの値である1つ目のパラメータにグローバルなthisオブジェクト、関数に渡す引数に"global"を渡している。
グローバルオブジェクトはグローバル変数をプロパティとして扱うためグローバル変数として宣言されているためthis.nameは"Kudo"となる。
2つ目、3つ目ではそれぞれ実行時のthisの値としてperson1,person2を指定しているため、それぞれのnameプロパティの値が出力される。
apply()メソッド概要
call()メソッドとほぼ同様。違いは2つ目のパラメータの関数に渡す引数が配列であることだけである。
function callFrom(idNumber){
console.log(idNumber + ":" + this.name);
}
var person1={
name:"Tanaka"
};
var person2={
name:"Sato"
};
var name="Kudo";
callFrom.apply(this,["global"]);
// global:Kudoと出力
callFrom.apply(person1,["person1"]);
// person1:Tanakaと出力
callFrom.apply(person2,["person2"]);
// person2:Satoと出力
ご覧の通りcall()メソッドとの違いは「2つ目のパラメータが配列であるか、配列でないか」のみである。
bind()メソッド概要
call()メソッドやapplyメソッドとは異なる機能を持っていて、bind()メソッドはthisの値を固定した新しい関数を生成する。新しく生成した関数の中身のロジックに関しては元となる関数と同じである。
1つ目のパラメータには新しい関数のthisとして固定される値を渡す。
2つ目のパラメータは任意指定で、指定する場合は新しい関数に渡す引数を渡す。
function callFrom(idNumber){
console.log(idNumber + ":" + this.name);
}
var person1={
name:"Tanaka"
};
var person2={
name:"Sato"
};
var name="Kudo";
// 新しい関数を生成する
var callFromPerson1 = callFrom.bind(person1);
callFromPerson1("person1");
// => person1:Tanaka と出力
// 新しい関数を生成する
var callFromPerson2 = callFrom.bind(person2, "person2");
callFromPerson2();
// => person2:Sato と出力
上記ではbind()メソッドによって2つの新しい関数を生成している。
新しく生成した1つ目の関数callFromPerson1ではthisの値をperson1に固定している。したがってthis.nameではperson1オブジェクトのnameを参照する。
2つ目の関数、callFromPerson2ではthisの値をperson2に固定している。また任意指定である2つ目の引数で関数に渡す引数"person2"を指定している。したがって関数呼び出し時にパラメータを指定することなく"person2"を出力することができている。
おわりに
JavaScriptのthisに関する挙動は、初心者や他の言語からやってきた方々にとっては、少しとっつきにくいものではないかと思う。(自分もいまだに苦戦中)
上記3つのメソッドを使いこなしてthisを自由に操れるようになりたいところ。