#thisのコントロール
開眼!javascriptを読んでて
thisとcallの動きについて知ったことがあり、書きますその2。
(※from 6章の6.5より。)
その1はこちら。
◼️グローバルなとこで使うthisはまじでグローバル
#thisレベル(thisに対する自分の理解感覚値)
関数とかの中でthis出てきたら「これ」の意味通り、その関数自体を指し示している、、、くらいの知識を持っていて、よくわかんなくなってもconsole.log()で中身見ればいいやくらいの理解度でした。
あとアロー関数の書き方くらいはわかるくらいの感じです!
#call()を使うとthisの生き方を決めれるぞ
どういう話かというと・・・
通常、「関数の中のthis」は、その関数自体を指し示します。
が、関数のcall()というものを使うと、任意の引数をthisの向き先に変えることができるぞ!というもの。
みんな大好きドラゴンボールの孫悟飯に例えます。
孫悟飯は子供の頃、学者になりたかったのですが、ピッコロに出会い、修行を受け、戦闘能力が上がり戦闘民族としての才能を開花させていきます。サイヤ人襲来編あたりの話です。
まず、「孫悟飯の情報を出力する無名関数」を作り、gohan変数に入れてみます。
//gohan変数に、関数を入れる。
var gohan = function(a,b){
this.life = a; //御飯の人生は引数a
this.sentouryoku = b; //御飯の戦闘力は引数b
console.log(this.life,this.sentouryoku) //御飯の人生と戦闘力を表示。
};
この関数ですが、受け取ったa、bの引数をもとに生活と戦闘力を決め、
gohan自体の情報を出力するというものです。
実際に、学者を目指してた子供自体の孫悟飯でやってみましょう。
初期のご飯の戦闘力は1ですね。ラディッツに切れた一発ぶちかましたあとがくんと戦闘力が下がるやつです。
var gohan = function(a,b){
this.life = a;
this.sentouryoku = b;
console.log(this.life,this.sentouryoku)
};
gohan("学者",1);
//この結果は 学者 1 となります。
###で、call()関数。
ここまでの内容を前提として、call()のなかのthisの扱いについてです。
これは、関数.call(a,b,c)とすると、その関数のthisの向き先を、「関数自体」ではなく、「a」にする、、、というものです。
わかりづらいので、とりあえず
孫悟飯の人生と戦闘力を、ピッコロに会うことで変えてみましょう。
#孫悟飯の人生をピッコロと会うことで変える
//ピッコロオブジェクトを作る
var picoro = {}
//この関数自体は同じです。
var gohan = function(a,b){
this.life = a;
this.sentouryoku = b;
console.log(this.life,this.sentouryoku)
};
//call関数。
gohan.call(picoro,"戦闘民族",2300);
//結果は、、、戦闘民族 2300
###何が起きたのか?
gohan.call(picoro,"戦闘民族",2300);
この記述の解説です。
先ほど書いたように、call関数は
一つ目の引数(つまりピッコロ)、を、this(孫悟飯の人生)の向き先にします。
孫悟飯は、出会った人の影響で人生が変わるわけなので、
つまりピッコロオブジェクトの中に、御飯の情報が入るわけです。
ここまで書いて少しこの例は違うなと気づき始めましたが、軌道修正も大変なのでこのまま行きます。
ピッコロオブジェクトに対して、つまりピッコロの人生の影響を受けて
御飯の人生もピッコロと同じようなものになったということです。
何を言ってるのかわからなくなってきましたが、どうあれこの結果は
戦闘民族 2300 とこうなります!
ちなみに、この記述の末尾に
console.log(picoro);
すると、きちんとピッコロオブジェクトの中身が出力されます。
赤字のとこ。
ピッコロオブジェクトの中にきちんと御飯の人生が入ってますね。
やっぱりこの例はなんか違いますが、call()の動きはこういうものです!はい成功!
##捕捉
ちなみに、apply()
という関数も同じようなことができます。
違いとしては、applyでは、引数を配列で渡せる、というものです。
gohan.call(picoro,"戦闘民族",2300);
のところを
gohan.apply(picoro,["戦闘民族",2300]);
とできるということです。
※結果は同じになります。
・参考
call関数