初めに
CallメソッドとApplyメソッドについて学習した内容のoutput用記事です。
※内容に間違いなどがある場合はご指摘をよろしくお願いします。
※こちらの記事はあくまでも個人で学習した内容のoutputとしての記事になります。
Callメソッド
関数を呼び出す際に、呼び出し元のthisがどのobjectなのかを指定します。
//構文
呼び出す関数.call(適用するobject, 関数の引数, 関数の引数2, ...);
使ってみる
まず、次のようなobjectを用意します。 trainオブジェクトにはprintTrain関数があり、コンソールにはtrainオブジェクトのtrainNameとdestination、そしてprintTrain関数の引数carNumとnameを表示します。また、trainオブジェクトにはdataというからの配列があり、printTrain関数を呼び出すとdataにtrainNameとcarNum、関数の引数nameを追加していきます。
const train = {
trainName: 'JR',
destination: 'Shibuya',
data: [],
printTrain(carNum, name) {
console.log(
` ${name} takes a train on ${this.trainName}.\n`,
`Bound for ${this.destination}.\n`,
`Car number is ${carNum}`
);
this.data.push({ TrainNumber: `${this.trainName}${carNum}`, name });
},
};
このtrainオブジェクトのprintTrain関数を呼び出します。引数には5と'Tom'を指定します。
train.printTrain(5, 'Tom');
コンソールには以下のような結果が表示されます。
trainオブジェクトの中身を確認してみます。
console.log(train);
trainオブジェクトのprintTrain関数を変数printTrainに格納します。これで変数printTrainはtrainオブジェクトの関数を保持しています。
const printTrain = train.printTrain;
この状態でprintTrainに引数を渡し、呼び出してみます。
printTrain(23, 'Tanaka');
TypeErrorが出てしまいます。内容としてはtrainNameが変数printTrainに定義されていないと表示されます。
これはtrainオブジェクトのprintTrain関数に指定されているthisがどのオブジェクトのthisなのかjavascriptが分からないことが原因です。オブジェクトの関数を他の変数に代入した時点でthisがグローバルコンテキストに変わったからです。
callメソッドを使い、thisがどのobjectなのかを指定(trainオブジェクトに指定)して引数と共に実行してみます。
printTrain.call(train, 332, 'Suzuki');
trainオブジェクトの中身を確認します。
console.log(train);
先ほど関数を呼び出した結果としてdata配列に値が追加されていることが分かります。
このようにcallメソッドを使うことによって呼び出す関数のthisがどのobjectなのかを指定し、関数の引数と共に結果を出力することができます。
参考サイト
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Function/call
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Function/apply