私は、Javascript のプロトタイプベースの継承モデルに頭を悩ませようとして、そのクラスベースの継承モデルを使用して Java のバックグラウンドを持っています。私をうんざりさせているのは、Java の「これ」の意味をしっかりと念頭に置いていることだと思います。Javascript の「これ」は非常に異なる獣です。Javascriptの「this」は、関数が定義されたスコープではなく、常に関数の呼び出し元を指すことを理解しています-つまり、それを読んで、それが何を意味するかを表面的に理解しています。でも、もっと深く理解してもらいたいので、別の呼び方がいいと思います。JSの「これ」についてどう思いますか?出くわすたびに精神的な交換をしますか?使用している場合、どの単語またはフレーズを使用していますか?
8 に答える
this
context
Javascriptで合理的に名前が変更される可能性があります。
これは実際には現在のスコープの実行コンテキストを参照しており、そのコンテキストはクラスのインスタンスにすることができますが、必ずしもそうである必要はありません。任意のオブジェクトにすることができ、実行時に変更できます。 。
Javascriptの「メソッド」が、それが定義されている「クラス」のインスタンスで動作しているという保証がまったくないことの証明:
function Cat(){
this.texture = 'fluffy';
this.greet = function(){
alert("Pet me, I'm " + this.texture);
}
}
var cat = new Cat();
// Default to using the cat instance as the this pointer
cat.greet(); // Alerts "Pet me, I'm fluffy"
// Manually set the value of the this pointer!
cat.greet.call({texture: 'scaly'}); // Alerts "Pet me, I'm scaly"
ここで重要なのは、オブジェクトの値はthis
、含まれている関数が定義されている場所とは完全に独立しているということです。
考えられる代替名の1つはowner
。です。これは、実行しているコードに応じて所有者が変更できる方向にあなたの心を導きます。
この例はquirksmodeからのものです:
JavaScriptではthis
、常に実行している関数の「所有者」を指します。つまり、関数がメソッドであるオブジェクトを指します。忠実な関数doSomething()をページで定義する場合、その所有者はページ、つまりJavaScriptのウィンドウオブジェクト(またはグローバルオブジェクト)です。ただし、onclickプロパティは、それが属するHTML要素によって所有されます。
次のコードでは、
function doSomething() {
this.style.color = '#cc0000';
}
と
element.onclick = doSomething;
、owner
実行時にメソッドを含むオブジェクトを指します。
------------ window --------------------------------------
| / \ |
| | |
| this |
| ---------------- | |
| | HTML element | <-- this ----------------- |
| ---------------- | | doSomething() | |
| | | ----------------- |
| -------------------- |
| | onclick property | |
| -------------------- |
| |
----------------------------------------------------------
皆さんが思っているよりも、 JavaScriptthis
は Java にずっと近いとthis
思います。OOP コンテキストでは、 this
「このインスタンス」を意味します。this
JavaScript のキーワードについて混乱を招く可能性があるのは、コンテキストによって意味が異なる可能性があることだと思います。
this
関数の呼び出し元 (そうかもしれませんが) または関数が定義されたスコープ (そうかもしれませんが) ではありません - それは関数のcontextです。
@Andrew Hareが言及している変化する意味は、おそらくあなたの混乱の原因に近いものです。JS のプロトタイプ継承メカニズムにより、キーワードは、使い方によっては、Java のメソッド定義よりも Javafunction
に近いものを意味する場合があります。class
ブラウザでの実行を想定:
var q = this.document; //this is window
var o = new (function pseudoconstructor(){
this.property = "something else" //the new keyword changed 'this' to mean 'the object I'm about to return'
})();
「JavaScript this」はいかがですか?それはあなたがしていることに直接結びつけられ、また、あなたが現在取り組んでいる「これ」の概念が JavaScript の概念であることを精神的に思い出させてくれます。
最終的には、「JavaScript this」と呼ぶのをやめて、単に「this」と呼び、作業中のコンテキストでそれが何を意味するかを十分に認識していると思います。とにかく、たどり着きます。
次のようなタイプしやすいメンタル モデルを少しだけ使って、新しい構文を吸収します。
$(document).ready(function() {
function baffle() {
alert(this.b);
}
function what() {
this.b = "Hello";
baffle();
}
function huh() {
this.b = "World";
baffle();
}
what();
huh();
}
);
これは、次のように、ずさんで架空の C++ にひどく変換されます。
template <class This>
function baffle() {
alert(This.b);
}
function what() {
b = "Hello";
baffle<what>();
}
function huh() {
b = "World";
baffle<huh>();
}
what();
huh();
this
歴史的な理由から最も適切だと思います。JavaScript には万能の for 句はありません。たとえば、手続き型関数のコンテキストやオブジェクトのコンテキストなど、this
非常に異なる参照に自動的に割り当てられるだけでなく、およびを使用してスクリプタによっても割り当てられます。this
this
this
Function.apply
Function.call
ただし、this
JavaScript と DOM はいくつかの非常に奇妙な方法で動作するため、 の意味は調整可能です。たとえば、 の主な用途はFunction.apply
、イベント呼び出しで要素参照のコンテキストを保持することです。Function.bind()
これは Prototye の方法で見たことがあるでしょう。
this
関数が実行されているコンテキストのプレースホルダーであり、それ以上具体的に取得するのは困難です。ただし、ほとんどの使用によりthis
、意味的に適切なキーワードになります。の場合、メソッドを使用して関数内でbind()
の意味を任意に変更していますが、メソッドを使用しない場合よりも適切にするために使用する必要があります。多くのアマチュア JavaScript プログラマーは、in イベント ハンドラーの奇妙な動作にうんざりしており、その「誤り」を正すことに慣れています。this
this
this
Function.apply
自己参照論理 (自己またはこれ) は、逆説を回避して、自己 (これ) 以外の作業を有利に進めます。自己 (これ) はすべてを 1 つに保ち、代わりにインスタンスなしでクラス メソッド (静的) を使用して静的なままにすることもできます。パラドックスを避けるために、自己参照を避け、ロジックはすべての真実を証明可能に保ち、その逆も同様です。