C、C#、または Java でのプログラミング経験がある人なら誰でも、this キーワードによく馴染みがあると思います。 Javascript はオブジェクト指向プログラミング言語であるため、C、C#、Java と同じように this キーワードが含まれています。 次に、JavaScript の this キーワードを紹介します。
多くのオブジェクトがあるため、指向プログラミング言語にはこのキーワードが含まれており、これは通常、コンストラクターを使用して新しく作成されたオブジェクトを指すことになります。 ECMAScript では、これは作成されたオブジェクトを表すだけでなく、実行コンテキストの属性としても使用されます:
まず、2 つのオブジェクト foo と person を定義します。foo には属性名が含まれ、person には属性名とメソッド Say() が含まれます。具体的な定義は次のとおりです。
say: function() {
alert(this === person);
this = foo; // ReferenceError
alert("私の名前は " this.name);
person.say (); // 私の名前は JK_Rush
ここで、say() メソッドで this の値を動的に変更します。上記のコードを再実行すると、this の値が正しく参照されていないことがわかります。これは、コード実行フェーズに入ると (特定のコードが実行される前に関数が呼び出されたとき)、 this の値が決定され、変更できないためです。
参照型
this の値はコンテキスト コードをアクティブにする呼び出し元によって決定されると前述しましたが、さらに重要なのは、this の値は呼び出し側の式の形式によって決まります。これの値に影響を与えるにはどうすればよいですか?
まず、内部型である参照型を紹介します。その値は、基本プロパティ (プロパティが属するオブジェクト) と基本オブジェクト内の propertyName という 2 つのプロパティを持つオブジェクトとして擬似コードで表現できます。属性:
// 参照型。 🎜>var valueOfReferenceType = {
base: mybase,
propertyName : 'mybasepropertyName'
};
参照型の値は次の 2 つの状況でのみ使用できます。 🎜>識別子を処理する場合
として使用する場合、または属性にアクセスする場合、
識別子は実際には変数名、関数名、関数パラメータ名、グローバル オブジェクトの無制限の属性になります。
//
var を宣言します。 foo = 23 ;
// 関数を宣言します
function Say() {
// コード。
中間プロセスでは、対応する参照型が使用されます。
var fooReference = {
ベース: グローバル,
プロパティ名: 'foo'
};
var SayReference = {
ベース: グローバル,
プロパティ名: 'say'
};
JavaScript でプロパティにアクセスするには、ドット表記と角括弧表記の 2 つの方法があることがわかっています。
foo.say()
foo['say']( );
say( ) メソッドは識別子であるため、次のように foo オブジェクト参照型に対応します:
var fooSayReference = {
base: foo,
propertyName: 'say'
};
say() が見つかりました。メソッドの基本属性値が foo オブジェクトの場合、それに対応する this 属性も foo オブジェクトを指します。
say() メソッドを直接呼び出し、対応する参照型が次のとおりであるとします。
var SayReference = {
base: global,
propertyName: 'say'
}; >
say() メソッドの基本属性値はグローバル (通常はウィンドウ オブジェクト) であるため、対応するこの属性もグローバルを指します。
関数コンテキスト内の this の値は関数呼び出し元によって提供され、現在の呼び出し式の形式によって決定されます。呼び出し括弧 () の左側に参照型値がある場合、その値は参照型値の基本オブジェクトに設定されます。 他のすべての場合 (非参照型)、this の値は常に null です。ただし、null には意味がないため、暗黙的にグローバル オブジェクトに変換されます。
関数呼び出しと非参照型
呼び出し括弧の左側が非参照型の場合、this の値は null に設定され、最終的には暗黙的にグローバル オブジェクトに変換されることを前述しました。
ここで、匿名の自己実行関数を定義します。具体的な実装は次のとおりです:
コードをコピー
コードは次のとおりです。 // 匿名関数を宣言します (function () { alert(this); // null => global
})();
括弧()の左側の匿名関数は非参照型オブジェクト(識別子でもプロパティアクセスでもない)なので、この値はグローバルオブジェクトに設定されます。
コードをコピー
コードは次のとおりです:
// オブジェクトを宣言します。
var foo = {
bar: function () {
alert(this);
}; bar)(); // foo.bar = foo.bar); // グローバル? foo.bar, foo.bar)(); // global
ここで、4 つの式のうち、最初の式だけが foo オブジェクトを指しており、他の 3 つの式は実行されることに注意してください。グローバル。
ここで別の疑問が生じます。プロパティにアクセスするのに、その最終値が参照型オブジェクトではなくグローバル オブジェクトになるのはなぜですか?
式 2 は代入演算子であることに気付きました。演算子の式セットとは異なり、GetValue メソッドの呼び出しがトリガーされます (11.13.1 の 3 番目のステップを参照)。 最終的に返されるときは、(参照型の値ではなく) 関数オブジェクトになります。つまり、 this の値は null に設定され、最終的にはグローバル オブジェクトになります。
3 番目と 4 番目のケースは似ています。カンマ演算子と OR 論理式は GetValue メソッドの呼び出しをトリガーします。したがって、元の参照型の値は失われ、関数型になり、この値はグローバルオブジェクト。
参照型と this の null 値
前述の状況では、呼び出し側の式の左側が参照型の値であっても、this の値が null である場合、例外が発生します。オブジェクト(グローバルオブジェクト)になります。 これが発生する条件は、参照型値の基本オブジェクトがたまたまアクティベーション オブジェクトである場合です。
これは、内部の子関数が親関数で呼び出されたときに発生します。アクティブなオブジェクトは次の回路図コードによって導入されます:
コードをコピー
alert(this); / global }
// AO.bar() と同じです。
bar();
}
アクティブ化オブジェクトは常にこの値を返します。 is - null (擬似コードを使用して AO.bar() が null.bar() と同等であることを表す)、この値は最終的に null からグローバル オブジェクトに変換されます。
関数呼び出しが with ステートメントのコード ブロック内に含まれており、with オブジェクトに関数属性が含まれている場合、例外が発生します。 with ステートメントは、オブジェクトをスコープ チェーンの先頭、アクティブ オブジェクトの前に追加します。 同様に、参照型の値 (識別子またはプロパティ アクセス) の場合、基本オブジェクトはアクティブ オブジェクトではなくなり、with ステートメントのオブジェクトになります。さらに、これは内部関数だけでなくグローバル関数にも適用されることに注意してください。その理由は、 with オブジェクトがスコープ チェーン内の上位レベルのオブジェクト (グローバル オブジェクトまたはアクティブ オブジェクト) をマスクするためです。コンストラクターとして 呼び出されたときの this の値
関数がコンストラクターとして使用される場合、new 演算子を通じてインスタンス オブジェクトを作成すると、その後 Foo() 関数の内部 [[Construct]] メソッドが呼び出されます。オブジェクトが作成されると、内部の [[Call]] メソッドが呼び出され、すべての Foo() 関数の this の値が新しく作成されたオブジェクトに設定されます。
コードをコピー
var foo = new Foo(); = 23; alert(foo.x); // 23 関数が呼び出されたときに this の値を手動で設定します。
Function.prototype はプロトタイプで 2 つのメソッドを定義します。関数を呼び出すときに this の値を指定します。これら 2 つのメソッドは、.apply() と .call() です。どちらのメソッドも呼び出しコンテキストの this の値として最初のパラメーターを受け取ります。2 つのメソッドの違いは、 .apply() メソッドの場合、2 番目のパラメーターは配列型 (またはオブジェクトのクラス Array) を受け取ります。 .call() メソッドは任意の数の引数 (カンマで区切られます) を受け入れますが、必要なのはこれら 2 つのメソッドの最初の引数、つまり this の値だけです。
サンプルコードを通じて call() メソッドと apply() メソッドの使用方法を紹介します:
コードをコピー
コードは次のとおりです。
myFunction.call(myObject, 'foo', 'bar'); // オブジェクト {foo = 'foo', bar = ' bar'}
console.log(myObject)
;
call() メソッドの最初のパラメータは必要な値です。次に、apply() メソッドの使用法を紹介します。
var myObject = {}; var myFunction = function(param1, param2) {
//apply() によって設定され、関数が呼び出されたときに私のオブジェクトを指します
this.foo=param1
this.bar=param2; >// ログ Object{foo='foo', bar='bar'}
console.log(this)
}// 関数を呼び出し、この値を設定します
myFunction.apply (myObject, ['foo', 'bar']);
// ログ オブジェクト {foo = 'foo', bar = 'bar'}
console.log(myObject);
call() メソッドと比較すると、メソッドのシグネチャが異なることを除けば、apply() メソッドと call() メソッドには大きな違いがないことがわかりました。
1.1.3 概要
この記事では、JavaScript での this の使用法を紹介します。さらに重要なことに、グローバル、関数、コンストラクターと、いくつかの特殊な場合における中央値の変更。
関数コンテキスト内の this の値は関数呼び出し元によって提供され、現在の呼び出し式の形式によって決定されます。呼び出し括弧 () の左側に参照型値がある場合、その値は参照型値の基本オブジェクトに設定されます。 他のすべての場合 (非参照型)、this の値は常に null です。ただし、null には意味がないため、暗黙的にグローバル オブジェクトに変換されます。 特殊なケースでは、代入演算子、カンマ演算子、および || を使用すると、this が元の参照型の値を失い、関数型になり、
参考
[1]
http://dmitrysoshnikov.com/ecmascript/chapter-3-this/
英語版
[2]
http://ブログ。 goddyzhao.me/post/11218727474/this
翻訳
[3]
https://net.tutsplus.com/tutorials/javascript-ajax/ fully- Understanding-the-this-keyword/ [作者]: JK_Rush