JavaScript アドバンス

JavaScript の call() メソッド

1. call() メソッドの概要

call() メソッドは、特定の this を指定して関数を呼び出すために使用されます。
call() を使用することで、あるオブジェクトが持つメソッドを別のオブジェクトで利用できるようになります。
これにより、同じ メソッド(Method)異なるオブジェクト に対して再利用することが可能になります。

call() はアドバンスド(高度)なトピックです。
先に進む前に、必ず this キーワードについての基本を理解しておいてください。

2. call() の基本構文

call() メソッドは、オブジェクトを引数として関数を呼び出すために使用されます。

  • 第1引数には、その関数内で this として参照させたいオブジェクトを渡します。
  • 第2引数以降には、関数に渡す引数をカンマ区切りのリストとして記述します。

2.1 構文

functionName.call(thisArg, arg1, arg2, ...);

3. call() を使った this の設定

call() を使うと、this がどのオブジェクトを参照すべきかを明示的に決定できます。
以下の例では、greet 関数が greeting + this.name を返します。
call() を使用することで、thisperson3 オブジェクトを指すように指定しています。

3.1 実装例

const person1 = { name: "John" };
const person2 = { name: "Paul" };
const person3 = { name: "Ringo" };

function greet(greeting) {
  return greeting + " " + this.name;
}

// this を person3 に指定して呼び出し
greet.call(person3, "Hello");

4. 他のオブジェクトからのメソッド借用

call() を使うことで、他のオブジェクトから メソッドを借用(Borrowing) することができます。

4.1 例1:person1 に対してメソッドを適用する

person オブジェクトの fullName メソッドを、person1 に対して呼び出します。

const person = {
  fullName: function() {
    return this.firstName + " " + this.lastName;
  }
}
const person1 = {
  firstName: "John",
  lastName: "Doe"
}
const person2 = {
  firstName: "Mary",
  lastName: "Doe"
}

// "John Doe" を返します
person.fullName.call(person1);

4.2 例2:person2 に対してメソッドを適用する

同じ person.fullName メソッドを、person2 に対して呼び出します。

const person = {
  fullName: function() {
    return this.firstName + " " + this.lastName;
  }
}
const person1 = {
  firstName: "John",
  lastName: "Doe"
}
const person2 = {
  firstName: "Mary",
  lastName: "Doe"
}

// "Mary Doe" を返します
person.fullName.call(person2);

5. 引数を伴う call() メソッド

call() メソッドは引数を受け取ることができます。
引数は、通常通りカンマで区切って渡します。

5.1 実装例

const person = {
  fullName: function(city, country) {
    return this.firstName + " " + this.lastName + "," + city + "," + country;
  }
}

const person1 = {
  firstName: "John",
  lastName: "Doe"
}

// 第2引数以降に city と country を渡す
person.fullName.call(person1, "Oslo", "Norway");

6. call() と通常の関数呼び出しの比較

通常の関数呼び出しと call() を使った呼び出しを比較してみましょう。

6.1 実装例

function showName() {
  return this.name;
}

const person = { name: "John" };

showName();             // call なし:this は person オブジェクトになりません
showName.call(person);  // call あり:this は明示的に設定されます

call() を使わない場合、this の参照先は実行環境(ブラウザなら window など)に依存しますが、call() を使うことで特定のオブジェクトを確実に紐付けることができます。

7. call() は新しい関数を作成しない

call() メソッドは、その場で 関数を即座に実行 します。
bind() メソッドのように、新しい関数を返して後で実行できるようにするものではありません。

7.1 実装例

function sayHello() {
  return "Hello " + this.name;
}

const person = { name: "John" };

// その場ですぐに実行される
sayHello.call(person);

もし、this の値を固定した(バインドした) 新しい関数を作成したい場合 は、call() ではなく bind() を使用してください。