JavaScript - 関数の間接的呼び出し

call メソッド

call はすべての関数に対して利用できるメソッドで this を特定の値に指定した上で関数を呼び出すことができます。call の第 1 引数には this を束縛したい値を指定します。そして残りの引数は呼び出す関数の引数となります。

// 'use strict'; /* 有効にすると greet() がエラーになる */
const bruce = { name: "Bruce" };
const madeline = { name: "Madeline" };

// call を使えば this が使えるようになる
function greet() {
    return `I'm ${this.name}.`;
}

console.log(greet());              // I'm undefined.
console.log(greet.call(bruce));    // I'm Bruce.
console.log(greet.call(madeline)); // I'm Madeline.
call メソッド

次の例のように call をオブジェクトの内容を書き換えるのにも使うことができます。

const bruce = { name: "Bruce" };
const madeline = { name: "Madeline" };

function update(birthYear, occupation) {
    this.生年 = birthYear;
    this.職業 = occupation;
}

console.log(bruce); // { 'name': 'Bruce' }
update.call(bruce, 1949, '歌手');
console.log(bruce); // { 'name': 'Bruce', '生年': 1949, '職業': '歌手' }

console.log(madeline); // { 'name': 'Madeline' }
update.call(madeline, 1942, '女優');
console.log(madeline); // { 'name': 'Madeline', '生年': 1942, '職業': '女優' }
call メソッド

apply メソッド

applycall とよく似ていますが引数の扱いが少し異なります。call は普通の関数と同じように引数を直接受け取りますが、apply は引数を配列として受け取ります。

const bruce = { name: "Bruce" };
const madeline = { name: "Madeline" };

function update(birthYear, occupation) {
    this.生年 = birthYear;
    this.職業 = occupation;
}

console.log(bruce); // { 'name': 'Bruce' }
update.apply(bruce, [1955, "俳優"]);
console.log(bruce); // { 'name': 'Bruce', '生年': 1955, '職業': '俳優' }

console.log(madeline); // { 'name': 'Madeline' }
update.apply(madeline, [1918, "ライター"]);
console.log(madeline); // { 'name': 'Madeline', '生年': 1918, '職業': 'ライター' }
apply メソッド

既に配列が用意されていてその値を関数の引数として使いたい場合は apply が便利です。例えば、配列の最大値や最小値を求める場合、関数 Math.minMath.max には任意個の引数を指定できるので、次のように apply を使うことができます。

'use strict';
const arr = [2, 3, -5, 15, 7];
console.log(Math.min.apply(null, arr)); // -5
console.log(Math.max.apply(null, arr)); // 15
apply メソッド

ここでは this の値として null を渡しています。Math.minMath.max では this は使われないので、何を渡しても影響ありません。展開演算子を使うと apply と同じ結果を得ることができます。update に関しては this の値が関係しますので call を使う必要があります。ただし、Math.minMath.max については this の値は関係しないので、展開演算子を使って直接呼び出せます。

'use strict';
const arr = [2, 3, -5, 15, 7];
console.log(Math.min(...arr)); // -5
console.log(Math.max(...arr)); // 15
展開演算子

bind メソッド

bindthis の値をある関数と永続的に結びつけることができます。

const bruce = { name: "Bruce" };
const madeline = { name: "Madeline" };

function update(birthYear, occupation) {
    this.生年 = birthYear;
    this.職業 = occupation;
}

const updateBruce = update.bind(bruce);

console.log(bruce); // { 'name': 'Bruce' }
updateBruce(1904, "俳優");
console.log(bruce); // { 'name': 'Bruce', '生年': 1904, '職業': '俳優' }

console.log(madeline); // { 'name': 'Madeline' }
updateBruce.call(madeline, 1274, "王様");
console.log(madeline); // { 'name': 'Madeline' }

/* bruce が変わってしまう */
console.log(bruce); // { 'name': 'Bruce', '生年': 1274, '職業': '王様' }
bind メソッド

bind は永続的な束縛を行うため、callapply あるいは bind を使っても効果が出なくなるため注意が必要です。

bind に引数を渡すことで特定の引数とともに呼び出される新しい関数を作ることができます。たとえば bruce の生年をいつも 1949 に設定する update にしたいが、職業の変更はしたいという場合、次のようにすることができます。

const bruce = { name: "Bruce" };

function update(birthYear, occupation) {
    this.生年 = birthYear;
    this.職業 = occupation;
}

const updateBruce1949 = update.bind(bruce, 1949);

console.log(bruce); // { 'name': 'Bruce' }
updateBruce1949("作詞家");
console.log(bruce); // { 'name': 'Bruce', '生年': 1949, '職業': '作詞家' }
bind メソッド

関連記事

JavaScript のまとめページはプログラミング JavaScript 入門を参照してください。

Category:
プログラミング
公開日:
更新日:
Pageviews:
22
Shares:
0
Tag:
JavaScript
hatebu icon
hatebu