この記事では、JavaScriptにおける thisについて説明したいと思います。thisの動作メカニズムを理解する助けになれば幸いです。JavaScriptプログラマーとして、thisについて学ぶことはとても役に立ちます。この投稿は、私の最近の仕事、つまりもうすぐ完成する私の本「 Application Design」の****章に触発されて書いたもので、スコープがどのように機能するかについて書いています。スコープがどのように機能するかという側面について。
"これ "に対してあなたが感じているのは、おそらく "もっともらしい否認 "でしょう:
[]
クレイジーでしょう?この短い記事では、その謎を解き明かしたいと思います。
これ」はどのように機能するのですか?
関数がオブジェクトのメソッドとして呼び出された場合、thisはそのオブジェクトに代入されます。
var parent = {
method: function () {
console.log(this);
}
};
parent.method();
// <- parent
メソッドへの参照を取得してそれを呼び出すと、thisの値はもはや親ではなく、ウィンドウ・グローバル・オブジェクトになります。これはほとんどの開発者を混乱させます。
var parentless = parent.method;
parentless();
// <- Window
要するに、呼び出された関数がオブジェクトのプロパティなのか、それ自身なのかを理解するために、呼び出しの連鎖を見る必要があるということです。プロパティとして呼び出された場合、thisの値はそのプロパティのオブジェクトになり、そうでなければ thisの値はグローバルオブジェクトまたはウィンドウに代入されます。の値は未定義になります。
コンストラクタとして扱われる場合、newキーワードが使われると、生成されるインスタンス・オブジェクトに thisが代入されます。
function ThisClownCar () {
console.log(this);
}
new ThisClownCar();
// <- ThisClownCar {}
この場合、関数をコンストラクタとして使うかどうかを判断する方法がないため、newキーワードを省略すると、上のように親の呼び出しがない thisがグローバルオブジェクトになることに注意してください。
ThisClownCar();
// <- Window
this」を変更。
.callメソッド、.applyメソッド、.bindメソッドは、関数の呼び出し方法を操作するために使用され、thisの値や関数に渡される引数の値を定義するのに役立ちます。
Function.prototype.callは任意の数の引数を持つことができ、***1つは thisに代入され、残りは呼び出し関数に渡されます。
Array.prototype.slice.call([1, 2, 3], 1, 2)
// <- [2]
Function.prototype.applyは.callのような動作をしますが、任意の引数の代わりに引数の配列を関数に渡します。
String.prototype.split.apply('', ['.'])
// <- ['13', '12', '02']
Function.prototype.bindは、.bindに渡された引数を常に thisの値として使用する特別な関数を作成します。また、部分的な引数を割り当てる機能もあり、元の関数のCoriolisバージョンを作成します。
var arr = [1, 2];
var add = Array.prototype.push.bind(arr, 3);
// effectively the same as arr.push(3)
add();
// effectively the same as arr.push(3, 4)
add(4);
console.log(arr);
// <- [1, 2, 3, 3, 4]
スコープチェーン内の this
次の例では、this はスコープチェインで変更されません。これはルールの欠陥であり、素人の開発者をしばしば混乱させます。
function scoping () {
console.log(this);
return function () {
console.log(this);
};
}
scoping()();
// <- Window
// <- Window
this "への参照を保持するローカル変数を作成する一般的な方法があり、子スコープに同じ名前の変数を持つことはできません。子スコープの同名の変数は、親スコープの this への参照を上書きします。
function retaining () {
var self = this;
return function () {
console.log(self);
};
}
retaining()();
// <- Window
親スコープの thisと、現在の thisの値の両方をどうしても使いたいのでなければ、不可解な理由ですが、私はmethod.bind関数を使うことを好みます。これを使えば、親スコープの this を子スコープに代入することができます。
function bound () {
return function () {
console.log(this);
}.bind(this);
}
bound()();
// <- Window
他に質問は?
これ」について何か質問はありますか?これ」についてはどうですか?もし私が他の境界ケースやエレガントな解決策を見逃していると思われるなら、ぜひ教えてください!
この投稿を楽しんでいただけたなら、私の近刊『JavaScript Application Design| アプリケーションデザイン』をぜひチェックしてください。