
なんだか関数がうまく動かないにゃ!

プログラマーさん
thisの中身って意識してる?
bind()を使った方がいいかも。。。

thisはthisじゃないのかにゃ?
訳の分からないこと言わないでほしいにゃ。。。
JavaScriptの挙動が思ったとおりにならない。そんな時にthisが予想外の要素を参照していることがあります。
今回はthisの中身を固定させるbind()メソッドについて解説していきます。
そもそもthisってなに?
まずbind()を理解するには、JavaScript の「this」の働きについて知っておく必要があります。
簡単に言うと:
- thisは「今、誰がこの関数を呼び出しているか?」を指します。
例:
const user = {
name: "ぽんきち",
sayHello: function() {
console.log("こんにちは、" + this.name + "です!");
}
};
user.sayHello(); // → こんにちは、ぽんきちです!
ここでのthisはuserを意味しておりthis.nameはuser.name(=”ぽんきち”)を指します。
でも、thisは変わってしまうことがある。
JavaScriptでは関数を「そのまま」他の場所に渡したりすると、thisの意味が変わってしまうことがあります。
例:
const user = {
name: "ぽんきち",
sayHello: function() {
console.log("こんにちは、" + this.name + "です!");
}
};
const hello = user.sayHello;
hello(); // → こんにちは、undefinedです!
これはhelloに代入されたseyHelloから見たthisがuserを指していないから。
hello()という関数単体として呼び出してしまっているからですね。
(const helloは関数であり、hello自身はnameを持っていないためundefinedになる。)
ここでbind()メソッドの登場
bind()メソッドを使うと、関数の中のthisを固定することができます。
使い方:
const 新しい関数 = 元の関数.bind(thisを固定したいオブジェクト);
使用例:
const user = {
name: "ぽんきち",
sayHello: function() {
console.log("こんにちは、" + this.name + "です!");
}
};
const hello = user.sayHello.bind(user);
hello(); // → こんにちは、ぽんきちです!
このようにbind()の第一引数にthisを固定したいオブジェクトを指定することで、hello()が呼ばれた時にthisはhello()自身を見ずに、userを見てくれるようになります。
また、既に引数が存在する関数をbind()で固定する場合は、bindの第二引数から順番に引数を渡してあげれば大丈夫です。
例:
const user = {
name: "ぽんきち",
greet: function(message, text) {
console.log(message + ", " + this.name + text);
}
};
const greetPonkichi = user.greet.bind(user, "こんにちは", "!");
greetPonkichi(); // → こんにちは, ぽんきち!
こんなかんじ。
bind()の応用:イベントハンドラで使う
DOMイベントなどでもthisが意図しないものになることがあります。
const user = {
name: "ぽんきち",
handleClick: function() {
console.log(this.name + "がクリックしました!");
}
};
const button = document.querySelector("button");
button.addEventListener("click", user.handleClick);
JavaScript では、DOMのaddEventListener()に渡された関数の中のthisはイベントを発生させた要素(今回ならbutton)になるため、ボタンをクリックしてもうまく動きません。(buttonはnameを持っていない)
こんな時もbind()で解決することができます。
const user = {
name: "ぽんきち",
handleClick: function() {
console.log(this.name + "がクリックしました!");
}
};
const button = document.querySelector("button");
button.addEventListener("click", user.handleClick.bind(user));
// → ぽんきちがクリックしました!
まとめ
- thisは関数を「誰が呼んだか」で変わる。
- bind()を使うと関数の中のthisを固定することができる。
- DOMのイベントハンドラなどでは特に便利。
ちなみにアロー関数はthisを持たないという性質もあるため、場合によってはbindがいらない時もありますが、それはまた別のお話。。。

なんとなくわかった気がするから意識して使ってみるにゃァ

プログラマーさん
うんうん。
その意気だね。