ホームページ  >  記事  >  ウェブフロントエンド  >  Javascript this_javascript スキルの学習概要

Javascript this_javascript スキルの学習概要

WBOY
WBOYオリジナル
2016-05-16 17:51:17985ブラウズ
1.1.1 概要
C、C#、または Java でのプログラミング経験がある人なら誰でも、this キーワードによく馴染みがあると思います。 Javascript はオブジェクト指向プログラミング言語であるため、C、C#、Java と同じように this キーワードが含まれています。 次に、JavaScript の this キーワードを紹介します。
この記事のディレクトリ
グローバル コード内の this
関数内の this
参照型
関数呼び出しと非参照型
この
関数の参照型と null 値constructor 関数が呼び出されたときの this の値
関数が呼び出されたときに this の値を手動で設定します

1.1.2 Text

多くのオブジェクトがあるため、指向プログラミング言語にはこのキーワードが含まれており、これは通常、コンストラクターを使用して新しく作成されたオブジェクトを指すことになります。 ECMAScript では、これは作成されたオブジェクトを表すだけでなく、実行コンテキストの属性としても使用されます:
コピー コードコードは次のとおりです:

activeExecutionContext = {
// 変数オブジェクト。
VO: {...},
this: thisValue
};
グローバル コード内のこれ

コードをコピー コードは次のとおりです:
// グローバル スコープ
//
// グローバル オブジェクト
foo1 = "abc"
alert(foo1); // abc
// 明示的なプロパティof
// グローバル オブジェクト
this.foo2 = "def";
alert(foo2) // def
// グローバル オブジェクト
>var foo3 = "ijk";
alert(foo3); // ijk


これはグローバル コンテキスト内にあるため、前にグローバル プロパティ foo1、foo2、および foo3 を定義しました。したがって、その値はグローバル オブジェクトそのもの (ブラウザーのウィンドウ オブジェクト) です。これを次に関数で紹介します。
関数内の This
これが関数コード内にある場合、状況はさらに複雑になり、多くの問題が発生します。
関数コードにおけるこの値の最初の特徴 (そして最も重要な特徴) は、この値が関数に静的にバインドされていないことです。
前述の通り、thisの値は実行コンテキスト(Excution context)に入った時点で決定され、関数コード内ではその値は毎回異なります。
ただし、コードが実行されると、その値は変更できません。これはその時点ではまったく変数ではないため、これに新しい値を割り当てることは不可能です。
次に、具体的な例を通して関数内でこれを説明します。
まず、2 つのオブジェクト foo と person を定義します。foo には属性名が含まれ、person には属性名とメソッド Say() が含まれます。具体的な定義は次のとおりです。


コードをコピーします コードは次のとおりです:
// foo オブジェクトを定義します。
var foo = {
name: "Foo "
};
// person オブジェクトを定義します。
var person = {
name: "JK_Rush",
say: function() {
alert(this === person );
alert( "私の名前は " this.name);
person.say(); // 私の名前は JK_Rush
// foo です
// 同じ関数を参照してください。say
foo.say = person.say;
foo.say(); // 私の名前は Foo です。コードを実行すると、呼び出し元の person Say() メソッドを使用する場合、これは person オブジェクトを指し、foo の Say() メソッドが代入を通じて peson の Say() メソッドを指すことがわかります。 foo の Say() メソッドを呼び出すと、これが person オブジェクトではなく foo オブジェクトを指していることがわかります。これはなぜでしょうか。
まず、this の値は関数内では静的ではないことを知っておく必要があります。その値は、関数が呼び出される前に、呼び出し元によって決定されます。たとえば、関数の外部コンテキストを呼び出すと、コンテキスト コードがアクティブになります。さらに重要なのは、this の値は呼び出し側の式の形式によって決定されるため、this は関数に静的にバインドされません。
this は関数に静的にバインドされていないため、関数内で this の値を動的に変更できますか?



コードをコピーします


コードは次のとおりです:
// foo オブジェクトを定義します。 var foo = { name: "Foo" }; // 人物オブジェクトを定義します。 var person = {
name: "JK_Rush",
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 つの方法があることがわかっています。


コードをコピー コードは次のとおりです。 // Say メソッドを呼び出します。
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 である場合、例外が発生します。オブジェクト(グローバルオブジェクト)になります。 これが発生する条件は、参照型値の基本オブジェクトがたまたまアクティベーション オブジェクトである場合です。
これは、内部の子関数が親関数で呼び出されたときに発生します。アクティブなオブジェクトは次の回路図コードによって導入されます:




コードをコピー
コードは次のとおりです。 // foo 関数を宣言します。 function foo() { function bar() {
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 の値が新しく作成されたオブジェクトに設定されます。



コードをコピー

コードは次のとおりです: //コンストラクター 関数 Foo を宣言します() { // 新しいオブジェクト。this.x = 10;
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() メソッドの使用方法を紹介します:




コードをコピー

コードは次のとおりです。

var myObject = {}; var myFunction = function(param1, param2) { //setviacall()'this' 関数が呼び出されたときのオブジェクトを指します this.foo = param1; this.bar = param2; //logs オブジェクト{foo = 'foo', bar = 'bar'} console.log(this); }; // 関数を呼び出し、この値を myObject に設定します
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
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。