Javascript

【JavaScript】callとapplyについて理解をまとめる

こんにちは、ともです。

この記事ではJavaScriptのFunctionオブジェクトが提供するメンバーであるcallとapplyというメソッドについて僕の理解をまとめて行きます。

参考にしたものは下記です。

call/applyメソッドとは

call/applyメソッドを利用することで、オブジェクトに登録されたメソッドを実行することができます。

function hoge() {
  console.log('do hoge');
}
hoge();// do hoge
hoge.call();// do hoge
hoge.apply();// do hoge

単純にhoge();で実行しても、call();で実行しても、apply();で実行してもhogeメソッドを実行していることが分かります。

ここで1つの疑問が浮かびました。

call/applyメソッドで実行する意味は?

なぜ、call/applyでメソッドを実行するのか理解するためにはthisの振る舞いについて理解する必要があります。

thisの参照先に関する理解は下記の記事にまとめました。

thisの参照先はthisが記載された場所やstrictモードの違いによって変わります。

function hoge() {
  console.log(this);
}
hoge();// window
hoge.call();// window
hoge.apply();// window

グローバルコンテキストに記述されたメソッド内のthisキーワードの参照先はstrictモードでundefined、非strictモードでwindowです。

上記例ではhogeメソッド内のthisは非strictモードなのでwindowを参照することになります。

ではthisキーワードを参照先をwindowオブジェクトでは無く、別のオブジェクトに変更してhogeメソッドを実行するにはどのすれば良いのでしょうか。

そこでcall/applyメソッドが登場します。

call/applyを利用してみる

var data = 'Global data';
var obj1 = {
  data: 'obj1 data'
};
function hoge() {
  console.log(this.data);
}
hoge(); // Global data
hoge.call(obj1);// obj1 data
hoge.apply(obj1);// obj1 data

call/applyの第一引数にthisで参照して欲しいオブジェクトをしてしました。

  • hoge();の場合はthisの参照先のルールに基づきwindow
  • hoge.call(obj1);の場合は参照先にobj1を指定しているためobj1
  • hoge.apply(obj1);の場合は参照先にobj1を指定しているためobj1

では、call/applyの違いは何なのでしょうか?

call/applyの違い

利用方法は下記となっています。

func.call(thisArg, arg1, arg2, ...)
 func.apply(thisArg, [argsArray])

引数のリストをみると、

  • callはメソッド実行時の引数を1つ1つセットして実行
  • applyはメソッド実行時の引数を配列にまとめて実行

この違いだけです。

var name = 'Tokyo'
var pref = {
  name: 'Osaka'
}
function showName(family, name) {
  console.log(family + name + 'from:' + this.name);
}
showName('田中', '太郎'); // 田中太郎 from Tokyo
showName.call(pref, '田中', '太郎'); // 田中太郎 from Osaka
showName.apply(pref, ['田中', '太郎']); // 田中太郎 from Osaka

上記のように、callは1つ1つ、applyは配列として引数を渡しました。

thisの参照先もprefに変更できていることが分かります。

まとめ

call/applyについて理解をまとめました。

メソッド内のthisの参照先を変更するためにcall/applyを利用することが分かりました。

また、call/applyの違いは引数の与え方の違いだけでした。