1. JavaScriptのbindメソッドとは?基本と仕組みを解説
1.1 bindメソッドの概要
bind
メソッドは、関数のthis
を特定のオブジェクトに固定し、新しい関数を返すメソッドです。
function.bind(thisArg[, arg1, arg2, ...])
thisArg
: 新しい関数で使用するthis
の値。arg1, arg2, ...
: 新しい関数に固定する引数(オプション)。
1.2 thisの基本とバインドの必要性
JavaScriptでは、関数の実行コンテキストによってthis
の参照先が異なります。bind
を使うと、意図しないthis
の変更を防ぐことができます。
const user = {
name: "太郎",
greet: function() {
console.log(`こんにちは、${this.name}です!`);
}
};
const greetFunc = user.greet;
greetFunc(); // thisがuserを参照しないため、エラーまたはundefined
const boundGreet = user.greet.bind(user);
boundGreet(); // こんにちは、太郎です!
1.3 【図解】bindを使う前と後でthisがどう変わるか
実行環境 | this の参照 |
---|---|
メソッドとして実行 | this はオブジェクトを指す |
変数に代入して実行 | this は undefined または window を指す |
bind を使って固定 | this はオブジェクトを固定する |
1.4 call / apply との違い【表で比較】
メソッド | this の設定 | 引数の渡し方 | 戻り値 |
---|---|---|---|
bind | 設定したthis を維持 | 固定した引数をセット可能 | 新しい関数を返す |
call | 設定したthis を適用 | カンマ区切りで渡す | 関数を即時実行 |
apply | 設定したthis を適用 | 配列で渡す | 関数を即時実行 |
function greet(greeting) {
console.log(`${greeting}, ${this.name}です!`);
}
const user = { name: "花子" };
greet.bind(user, "こんにちは")(); // こんにちは、花子です!
greet.call(user, "こんばんは"); // こんばんは、花子です!
greet.apply(user, ["おはよう"]); // おはよう、花子です!
1.5 まとめ
bind
メソッドはthis
を固定し、新しい関数を作成する。this
の参照先が意図しないものになる場面で特に有効。bind
を使うと、関数のthis
を指定したオブジェクトに固定できる。call
やapply
とは異なり、新しい関数を作成するため、後で実行することが可能。
2. JavaScriptのbindの使い方と基本構文
2.1 bindの基本的な書き方
bind
メソッドの基本構文は以下の通りです。
function.bind(thisArg[, arg1, arg2, ...])
thisArg
:this
として設定したいオブジェクトarg1, arg2, ...
: 事前に渡しておく引数(省略可能)
2.2 bindの基本的な使い方
まず、bind
を使わずに関数を実行した場合と、bind
を使った場合を比較してみましょう。
bindを使わない場合
const person = {
name: "太郎",
greet: function() {
console.log(`こんにちは、${this.name}です!`);
}
};
const greetFunc = person.greet;
greetFunc(); // thisがpersonを参照しないため、エラーまたはundefined
bindを使った場合
const boundGreet = person.greet.bind(person);
boundGreet(); // こんにちは、太郎です!
2.3 bindメソッドの引数と戻り値
【例1】bindを使ってthisを固定する
const button = document.getElementById("myButton");
const obj = {
message: "クリックされました!",
handleClick: function() {
console.log(this.message);
}
};
// bindなし(thisがbuttonを指す)
button.addEventListener("click", obj.handleClick);
// bindあり(thisがobjを指す)
button.addEventListener("click", obj.handleClick.bind(obj));
2.4 【表】bindの引数の扱い方(thisのバインド+引数の部分適用)
メソッド | this の固定 | 引数の事前設定 | 実行タイミング |
---|---|---|---|
bind | 可能 | 可能 | 後で実行 |
call | 可能 | 不可能 | すぐ実行 |
apply | 可能 | 不可能 | すぐ実行 |
【例2】bindで引数を事前に設定する
function greet(greeting, punctuation) {
console.log(`${greeting}, ${this.name}${punctuation}`);
}
const person = { name: "太郎" };
const sayHello = greet.bind(person, "こんにちは");
sayHello("!"); // こんにちは, 太郎!
const sayGoodbye = greet.bind(person, "さようなら", "…。");
sayGoodbye(); // さようなら, 太郎…。
2.5 まとめ
bind
メソッドはthis
を固定し、新しい関数を作成する。bind
を使用すると、イベントハンドラやコールバック関数のthis
を明示的に指定できる。bind
はthis
の固定に加えて、部分適用のように事前に引数を設定することも可能。call
/apply
とは異なり、新しい関数を返すため、後で実行できるのが特徴。
3. JavaScriptのbindメソッドの実践的な使用例
3.1 thisの明示的な固定
thisが変わるケース
JavaScriptでは、関数がどこでどのように呼ばれるかによってthis
の参照先が変わるため、意図しない挙動が起こることがあります。
const person = {
name: "太郎",
greet: function() {
console.log(`こんにちは、${this.name}です!`);
}
};
const greetFunc = person.greet;
greetFunc(); // thisが意図したオブジェクトを指さないため、エラーまたはundefined
bindを使ってthisを固定
const boundGreet = person.greet.bind(person);
boundGreet(); // こんにちは、太郎です!
3.2 イベントハンドラでの活用
bindなし(thisが変更される例)
const button = document.getElementById("myButton");
const obj = {
message: "クリックされました!",
handleClick: function() {
console.log(this.message);
}
};
button.addEventListener("click", obj.handleClick); // thisはbuttonを参照し、エラーまたはundefined
bindを使ってthisを固定
button.addEventListener("click", obj.handleClick.bind(obj));
// クリックすると "クリックされました!" が表示される
3.3 部分適用関数の作成
bind
を使うと、関数の 一部の引数を固定する(部分適用) こともできます。
bindを使った部分適用の例
function multiply(a, b) {
return a * b;
}
// a を 2 に固定した関数を作成
const double = multiply.bind(null, 2);
console.log(double(5)); // 10
console.log(double(10)); // 20
3.4 クラス(コンストラクタ)での利用
クラスメソッド内でのthisの問題
class Counter {
constructor() {
this.count = 0;
}
increment() {
this.count++;
console.log(this.count);
}
}
const counter = new Counter();
const incrementFunc = counter.increment;
incrementFunc(); // thisがCounterを参照せず、エラーまたはundefined
bindを使ってthisを固定
class Counter {
constructor() {
this.count = 0;
this.increment = this.increment.bind(this); // thisを固定
}
increment() {
this.count++;
console.log(this.count);
}
}
const counter = new Counter();
const incrementFunc = counter.increment;
incrementFunc(); // 1
incrementFunc(); // 2
3.5 まとめ
bind
を使うと、関数をどこで呼び出してもthis
が正しく設定される。- イベントハンドラ での
this
の問題を回避できる。 - 部分適用関数 を作成し、より柔軟な関数を作れる。
- クラスのメソッド に適用することで、意図しない
this
の変更を防ぐ。
4. JavaScriptのbindメソッドの内部動作を解説
4.1 bindが実際にどのように機能するか
bind
メソッドを使用すると、新しい関数オブジェクトが作成され、その関数のthis
は指定されたオブジェクトに固定されます。
function greet() {
console.log(this.name);
}
const person = { name: "太郎" };
const boundGreet = greet.bind(person);
boundGreet(); // 太郎
このコードでは、bind
によってthis
がperson
に固定され、新しい関数boundGreet
が作成されています。
4.2 bindされた関数のprototypeはどうなる?
通常の関数はprototype
を持ちますが、bind
された関数はprototype
を持たず、新しいオブジェクトとして扱われます。
function Person(name) {
this.name = name;
}
const BoundPerson = Person.bind(null);
console.log(Person.prototype); // { constructor: ƒ }
console.log(BoundPerson.prototype); // undefined
bindを適用すると、コンストラクタ関数としては使えなくなる
const BoundPerson2 = Person.bind(null);
const p = new BoundPerson2("花子"); // TypeError: BoundPerson2 is not a constructor
4.3 【図解】bindはどのように関数を生成するのか?
操作 | 変更点 |
---|---|
bind 適用前 | this は実行時のコンテキストで決定 |
bind 適用後 | this が固定され、新しい関数が生成される |
bind 適用関数 | prototype がなくなるため、コンストラクタとして使えない |
4.4 thisのバインディングとクロージャの関係
JavaScriptでは、クロージャを使うことで関数が生成された時点の環境を保持できます。bind
メソッドはこの仕組みを活用して、this
を固定した新しい関数を作成します。
クロージャを使ったbindの再現
function customBind(func, thisArg) {
return function() {
return func.apply(thisArg);
};
}
function greet() {
console.log(this.name);
}
const person = { name: "太郎" };
const boundGreet = customBind(greet, person);
boundGreet(); // 太郎
4.5 まとめ
bind
を使うと、新しい関数オブジェクトが作成される。bind
された関数は、元の関数とは異なるため、prototype
を持たない。bind
は クロージャを活用してthis
を固定 した関数を作成する。bind
された関数は、コンストラクタとして使用できない。

5. JavaScriptのbindと他の関数メソッド(call / apply)との比較
5.1 bind / call / apply の違いとは?
bind
、call
、apply
は、すべてthis
を変更できるメソッドですが、動作が異なります。
bind / call / apply の違い(表で比較)
メソッド | this の設定 | 引数の渡し方 | 実行タイミング | 戻り値 |
---|---|---|---|---|
bind | 固定される | 部分適用可能 | 後で実行 | 新しい関数 |
call | 変更可能 | カンマ区切り | 即座に実行 | 関数の戻り値 |
apply | 変更可能 | 配列で渡す | 即座に実行 | 関数の戻り値 |
例
function greet(greeting) {
console.log(`${greeting}, ${this.name}`);
}
const person = { name: "太郎" };
// bind(新しい関数を作成)
const boundGreet = greet.bind(person, "こんにちは");
boundGreet(); // こんにちは, 太郎
// call(即時実行)
greet.call(person, "こんばんは"); // こんばんは, 太郎
// apply(即時実行、引数を配列で渡す)
greet.apply(person, ["おはよう"]); // おはよう, 太郎
5.2 bind / call / apply の使い分け
場面 | 使うべきメソッド | 理由 |
---|---|---|
this を固定した関数を作成したい | bind | 新しい関数を返す ため、後で実行できる |
this を指定しつつ即座に関数を実行したい | call | その場で関数を実行できる |
配列で引数を渡して即座に実行したい | apply | apply は 引数を配列で渡せる |
【例】Math.maxとapplyを使った例
const numbers = [10, 5, 8, 12, 3];
const maxNumber = Math.max.apply(null, numbers);
console.log(maxNumber); // 12
5.3 まとめ
bind
は新しい関数を作る(即時実行しない)。call
はthis
を指定して即座に実行(引数はカンマ区切り)。apply
はthis
を指定して即座に実行(引数は配列で渡す)。bind
は イベントリスナーやコールバック関数 でthis
を固定するのに便利。call
/apply
は 関数をすぐに実行したい場合に使う。apply
は 配列のデータを関数に渡す場合に便利(Math.max
など)。
6. JavaScriptのbindメソッドを使う際の注意点
6.1 bindを多用するとパフォーマンスに影響がある?
bindを使うと新しい関数が生成される
bind
を適用するたびに新しい関数オブジェクトが作成されるため、無駄なメモリ消費が発生することがあります。
function greet() {
console.log(this.name);
}
const person = { name: "太郎" };
// 毎回新しい関数が作られる
const greet1 = greet.bind(person);
const greet2 = greet.bind(person);
console.log(greet1 === greet2); // false(異なる関数)
対策:bindした関数をキャッシュする
const boundGreet = greet.bind(person);
boundGreet(); // 再利用可能
6.2 コンストラクタ関数との組み合わせ
bindを適用した関数はnew演算子と相性が悪い
function Person(name) {
this.name = name;
}
const BoundPerson = Person.bind(null);
const p = new BoundPerson("花子"); // TypeError: BoundPerson is not a constructor
対策:bindを使わずにthisを明示的にセットする
function Person(name) {
if (!(this instanceof Person)) {
return new Person(name);
}
this.name = name;
}
const p1 = new Person("花子");
const p2 = Person("太郎");
console.log(p1.name); // 花子
console.log(p2.name); // 太郎
6.3 イベントリスナーの削除が難しくなる
bindを使うとremoveEventListenerで削除できない
const button = document.getElementById("myButton");
const obj = {
message: "クリックされました!",
handleClick: function() {
console.log(this.message);
}
};
button.addEventListener("click", obj.handleClick.bind(obj));
button.removeEventListener("click", obj.handleClick.bind(obj)); // 削除できない
対策:bindした関数を変数に保存する
const boundHandleClick = obj.handleClick.bind(obj);
button.addEventListener("click", boundHandleClick);
button.removeEventListener("click", boundHandleClick); // 正しく削除できる
6.4 まとめ
bind
は毎回新しい関数を生成するため、多用するとメモリ消費が増える。- ✅ 対策:事前にbindした関数をキャッシュして再利用する。
- コンストラクタ関数に
bind
を適用すると、new
でのインスタンス生成ができなくなる。 - ✅ 対策:
this
を適切に管理し、new
が不要な場合は自動的に適用する。 bind
を使うと、removeEventListener
で削除が難しくなる。- ✅ 対策:事前にbindした関数を変数に保存し、
addEventListener
とremoveEventListener
で同じ関数を使う。
7. JavaScriptのbindメソッドに関するFAQ
7.1 bind
メソッドはどのような場面で使用すべきか?
bind
は、特に 関数のthis
が意図しないオブジェクトを指す 場面で活用されます。
✅ bind
が役立つ場面
- オブジェクトのメソッドを変数に代入すると
this
が変わるconst user = { name: "太郎", greet: function() { console.log(`こんにちは、${this.name}です!`); } }; const greetFunc = user.greet; greetFunc(); // thisがuserを参照しないためエラー const boundGreet = user.greet.bind(user); boundGreet(); // こんにちは、太郎です!
- イベントハンドラでの
this
の固定const button = document.getElementById("myButton"); const obj = { message: "クリックされました!", handleClick: function() { console.log(this.message); } }; button.addEventListener("click", obj.handleClick.bind(obj));
- 関数の引数を事前に設定する(部分適用)
function multiply(a, b) { return a * b; } const double = multiply.bind(null, 2); console.log(double(5)); // 10
7.2 bind
とcall
、apply
の違いは?
メソッド | this の設定 | 引数の渡し方 | 実行タイミング |
---|---|---|---|
bind | 固定される | 部分適用可能 | 後で実行 |
call | 変更可能 | カンマ区切り | 即座に実行 |
apply | 変更可能 | 配列で渡す | 即座に実行 |
例
function greet(greeting) {
console.log(`${greeting}, ${this.name}`);
}
const person = { name: "太郎" };
greet.bind(person, "こんにちは")(); // こんにちは, 太郎
greet.call(person, "こんばんは"); // こんばんは, 太郎
greet.apply(person, ["おはよう"]); // おはよう, 太郎
7.3 bind
を使うとメモリリークが起こる?
通常、bind
自体がメモリリークの直接的な原因にはなりませんが、bindを多用すると不要な関数オブジェクトが増え、メモリ消費が増加 する可能性があります。
❌ bindを多用すると問題が起こる例
function greet() {
console.log(this.name);
}
const person = { name: "太郎" };
const greet1 = greet.bind(person);
const greet2 = greet.bind(person);
console.log(greet1 === greet2); // false(毎回新しい関数が生成される)
✅ 対策:bindした関数をキャッシュして再利用
const boundGreet = greet.bind(person);
boundGreet();
7.4 bind
とアロー関数はどちらを使うべきか?
アロー関数(=>
)は this
を外側のスコープから継承 するため、
場合によってはbind
を使わなくてもthis
を固定できます。
✅ bind
を使わずにthisを固定する方法
const obj = {
message: "こんにちは!",
greet: () => {
console.log(this.message); // `this` は obj ではなく `window` を指す
}
};
obj.greet(); // undefined
❌ bind
が不要なケース(アロー関数を使う)
const button = document.getElementById("myButton");
button.addEventListener("click", () => {
console.log("クリックされました!");
});
7.5 まとめ
bind
はthis
を固定したいときに便利(イベントハンドラ、コールバック関数など)。bind
/call
/apply
はthis
を変更するが、実行タイミングと引数の渡し方が異なる。bind
の多用はメモリリークを引き起こす可能性があるため、適切にキャッシュを利用する。- アロー関数は
this
を継承するため、bindを使わなくても固定できる場合がある。
8. まとめ
8.1 JavaScriptのbindメソッドのポイント
bind
は、関数のthis
を特定のオブジェクトに固定する メソッド。bind
を適用すると、新しい関数 が作成される(元の関数は変更されない)。bind
を使うと、イベントハンドラやコールバック関数内でのthis
の参照先を適切に管理 できる。bind
は部分適用(関数の一部の引数を固定)にも使える。
8.2 bindが有効な場面と適切な活用方法
場面 | bind を使う理由 |
---|---|
オブジェクトのメソッドを変数に代入する | 変数に代入するとthis が失われるが、bind で固定できる |
イベントハンドラのthisを固定する | addEventListener 内のthis はデフォルトで要素を指すため、bind を使ってオブジェクトを参照させる |
部分適用関数を作る | 一部の引数を事前に固定し、再利用しやすい関数を作成できる |
非同期処理のコールバック関数 | 非同期関数の内部でthis を維持する |
✅ 具体例
const obj = {
message: "こんにちは!",
showMessage: function() {
console.log(this.message);
}
};
const show = obj.showMessage.bind(obj);
show(); // こんにちは!
8.3 bind / call / apply の使い分け
メソッド | this の設定 | 引数の渡し方 | 実行タイミング |
---|---|---|---|
bind | 固定される | 部分適用可能 | 後で実行 |
call | 変更可能 | カンマ区切り | 即座に実行 |
apply | 変更可能 | 配列で渡す | 即座に実行 |
✅ 簡単な例
function greet(greeting) {
console.log(`${greeting}, ${this.name}`);
}
const person = { name: "太郎" };
greet.bind(person, "こんにちは")(); // bind: こんにちは, 太郎
greet.call(person, "こんばんは"); // call: こんばんは, 太郎
greet.apply(person, ["おはよう"]); // apply: おはよう, 太郎
8.4 bindを使う際の注意点と対策
① bind
を多用するとメモリ消費が増える
- 問題:
bind
を適用するたびに新しい関数が作成される。 - 対策:事前に
bind
した関数をキャッシュ し、再利用する。
const boundGreet = greet.bind(person);
boundGreet(); // 再利用可能
② bind
を適用した関数はコンストラクタとして使用できない
- 問題:
bind
するとprototype
がなくなるため、new
でのインスタンス生成ができない。 - 対策:
bind
を使わず、関数内でthis
を適切に管理 する。
function Person(name) {
if (!(this instanceof Person)) {
return new Person(name);
}
this.name = name;
}
③ bind
を使うとremoveEventListener
で削除できない
- 問題:
bind
を適用すると、毎回異なる関数が生成されるため、removeEventListener
で削除できない。 - 対策:
bind
した関数を変数に保存 し、addEventListener
とremoveEventListener
の両方で同じ関数を使用する。
const boundHandleClick = obj.handleClick.bind(obj);
button.addEventListener("click", boundHandleClick);
button.removeEventListener("click", boundHandleClick); // 正しく削除できる
8.5 まとめ
✅ bind
メソッドは関数のthis
を固定し、新しい関数を作成する。
✅ bind
を使うと、this
の変更を防ぎ、コールバック関数やイベントハンドラでの不具合を解消できる。
✅ bind
はcall
やapply
とは異なり、関数を即座に実行せず、新しい関数を返す。
✅ bind
を使いすぎるとメモリ消費が増えるため、適切にキャッシュする。
✅ bind
を使うとremoveEventListener
で削除できなくなるため、変数に格納して管理する。