JavaScriptのコールバック関数内部のthisの指向問題と4つのバインディングthisの指向方法
1、よくあるコールバック関数の内部のthis指向問題については、まず以下のコードを見ます.
では、「calback」の「this」が対象の「o」を指し、「age」の値を得るにはどうすればいいですか?
2、結合thisが指す4つの方法2.1、方法1:【calback】の中の
2.2、方法2:【func】における【calback】の呼び出し方法
2.3、方法3:ES 6の方法を使う必要があります.(もしまだ習っていないなら、ついでに調べてもいいです.)、もうすぐ【say】の中の【calback】の定義方式です.
2.4、方法四:コードを変換する
var o = {
age : 12,
say : function() {
function callback() {
return this.age;
}
func(callback);
}
};
function func(callback) {
var name = "Xiao Ming";
console.log(name + " is " + callback() + " years old.");
}
o.say();
コード解析:ここでは、一例のオブジェクト「o」と一つの一般関数「func」を作成しました.「o」には、メソッド「say」に関数「func」を呼び出し、パラメータとしてコールバック関数「calback」にオブジェクト「o」の属性「age」を返しました.関数【func】に実行すると、印刷の結果は以下の通りです.console.log(name + " is " + callback() + " years old."); //Xiao Ming is undefined years old.
「Fnc」で実行されたコールバック関数「calback」の返却結果は「undefined」であって、「12」ではないことが分かります.関数内部の「this」は、この関数の使用者(所有者)を指します.上記の例では、「calback」関数は対象の「o」の「say」と定義されていますが、実際には「calback」は「func」関数で一般的に呼び出されていますので、「func」の「calback」の使用者は「window」の対象と理解できますので、「calback」の「this」はwindowを指します.グローバルスコープには変数【age】が存在しないため、「this.age」(つまり「window.age」)は存在せず、「undefined」に戻ります.ここでもう一つ言います.変数「age」が存在しない以上、未定義の変数を使う時にエラーが発生しません.ここでは「return this.age」ではなく「return window.age」です.つまり、オブジェクトの未定義の属性を使うとエラーが発生しません.「undefined」に戻ります.未定義の変数をそのまま使うとエラーが発生します.では、「calback」の「this」が対象の「o」を指し、「age」の値を得るにはどうすればいいですか?
2、結合thisが指す4つの方法2.1、方法1:【calback】の中の
return this.age;
に換えるreturn o.age;
もうすぐ【this】を具体的な対象【o】に変えます.このように、最後の印刷結果が正しいことを保証できます.console.log(name + " is " + callback() + " years old."); //Xiao Ming is 12 years old.
もちろん、この方法はちょっと問題があります.また、このような方法には問題があります.対象の内部は【o】であって、【this】ではなく対象名との結合性を深めます.2.2、方法2:【func】における【calback】の呼び出し方法
callback()
に換えるcallback.call(o)
またはcallback.apply(o)
またはcallback.bind(o)()
つまり、使い方【call/apply/bind】で【calback】内部の【this】を対象【o】に向けることで、正しい印刷結果が得られます.2.3、方法3:ES 6の方法を使う必要があります.(もしまだ習っていないなら、ついでに調べてもいいです.)、もうすぐ【say】の中の【calback】の定義方式です.
function callback() {
return this.age;
}
に換えるvar callback = () => this.age;
矢印関数で定義します.矢印関数内部の「this」の理解については、ここで阮先生の言葉を引用します.矢印関数は自分のthisがまったくないので、内部のthisは外層コードブロックのthisです.このように、ここで定義されている「calback」の関数内部の「this」は、「say」の方法の「this」であっても、「say」の方法はコードの最後に「o」で呼び出されるので、「say」の「this」は「o」を指しています.したがって、「calback」の中のthisの方向も「o」です.(印刷結果は同じです.この略)2.4、方法四:コードを変換する
var o = {
age : 12,
say : function() {
function callback(that) {
return that.age;
}
func(this, callback);
}
};
function func(that, callback) {
var name = "Xiao Ming";
console.log(name + " is " + callback(that) + " years old.");
}
o.say();
正しい【this】を【calback】に伝えることで、最後に正しい結果が得られることを保証しますが、ちょっと複雑です.(印刷結果は同じです.この略)