JavaScript上級者への道:call、apply、bindを使いこなしてコードをレベルアップ
JavaScriptにおけるcallとapplyの違い
共通点
- 関数を別のオブジェクトのコンテキストで呼び出す
this
キーワードの参照先を変更できる- 引数を個別に指定できる
相違点
項目 | call | apply |
---|---|---|
引数の渡し方 | 個別に指定 | 配列で指定 |
引数の個数 | 可変 | 可変 |
パフォーマンス | わずかに速い | わずかに遅い |
詳細
-
引数の渡し方
call
は、第二引数以降に個別に引数を指定します。
-
引数の個数
-
パフォーマンス
例
function greeting(name) {
console.log(`Hello, ${name}!`);
}
const person = {
name: 'John Doe',
};
// call
greeting.call(person, 'Jane Doe'); // Hello, Jane Doe!
// apply
greeting.apply(person, ['Jane Doe']); // Hello, Jane Doe!
上記例では、greeting
関数をperson
オブジェクトのコンテキストで呼び出しています。
使い分け
- 引数を個別に指定したい場合は
call
- パフォーマンスが重要な場合は
call
補足
bind
というメソッドも、this
キーワードの参照先を変更するために使用できます。call
、apply
、bind
は、オブジェクト指向プログラミングの重要な概念です。
call
function greeting(name) {
console.log(`Hello, ${name}!`);
}
const person = {
name: 'John Doe',
};
// call
greeting.call(person, 'Jane Doe'); // Hello, Jane Doe!
// callを使って、オブジェクトのプロパティにアクセスする
function getFullName() {
return `${this.firstName} ${this.lastName}`;
}
const user = {
firstName: 'John',
lastName: 'Doe',
};
const fullName = getFullName.call(user); // 'John Doe'
apply
function greeting(name) {
console.log(`Hello, ${name}!`);
}
const person = {
name: 'John Doe',
};
// apply
greeting.apply(person, ['Jane Doe']); // Hello, Jane Doe!
// applyを使って、配列の要素を個別に引数として渡す
function sumNumbers(a, b, c) {
return a + b + c;
}
const numbers = [1, 2, 3];
const sum = sumNumbers.apply(null, numbers); // 6
bind
function greeting(name) {
console.log(`Hello, ${name}!`);
}
const person = {
name: 'John Doe',
};
// bind
const boundGreeting = greeting.bind(person);
boundGreeting('Jane Doe'); // Hello, Jane Doe!
// bindを使って、新しい関数を生成する
function add(a) {
return this.b + a;
}
const obj = {
b: 10,
};
const add10 = add.bind(obj);
const result = add10(5); // 15
JavaScriptで関数を別のオブジェクトのコンテキストで呼び出すその他の方法
アロー関数を使用すると、this
キーワードの参照先を明示的に指定する必要がなく、簡潔にコードを書くことができます。
const person = {
name: 'John Doe',
};
const greeting = () => console.log(`Hello, ${this.name}!`);
greeting.call(person); // Hello, John Doe!
Proxyオブジェクトを使用すると、オブジェクトのプロパティやメソッドへのアクセスをインターセプトすることができます。
const person = {
name: 'John Doe',
};
const proxy = new Proxy(person, {
get(target, property) {
if (property === 'greeting') {
return function() {
console.log(`Hello, ${this.name}!`);
};
}
return target[property];
},
});
proxy.greeting(); // Hello, John Doe!
Function.prototype.bind
メソッドを使用すると、新しい関数を生成することができます。
function greeting(name) {
console.log(`Hello, ${name}!`);
}
const person = {
name: 'John Doe',
};
const boundGreeting = greeting.bind(person);
boundGreeting(); // Hello, John Doe!
これらの方法はそれぞれ異なる利点と欠点があるため、状況に応じて使い分ける必要があります。
javascript function performance