ホームページ > 記事 > ウェブフロントエンド > JavaScript_javascript ヒントのこのキーワードの図
JavaScript は、関数型プログラミング、クロージャ、プロトタイプベースの継承などの高度な機能をサポートするスクリプト言語です。 JavaScript は最初は簡単に始められるように見えますが、より深く使用するにつれて、JavaScript を習得するのは実際には非常に難しく、いくつかの基本概念が混乱していることがわかります。その中でも、JavaScript の this キーワードは比較的わかりにくい概念であり、さまざまなシナリオでさまざまなオブジェクトに変換されます。 JavaScript の this キーワードを正しくマスターすることによってのみ、JavaScript 言語の限界に入ることができるという見方があります。主流のオブジェクト指向言語 (Java、C# など) では、この意味は明確かつ具体的です。つまり、現在のオブジェクトを指します。通常はコンパイル時にバインドされます。 JavaScript では、this は実行時にバインドされます。これが、JavaScript の this キーワードが複数の意味を持つ重要な理由です。
実行時の JavaScript バインディングの性質により、JavaScript の this は、関数の呼び出し方法に応じて、グローバル オブジェクト、現在のオブジェクト、または任意のオブジェクトになります。 JavaScript で関数を呼び出す方法はいくつかあります。オブジェクト メソッドとして、関数として、コンストラクターとして、および apply または call を使用します。よく言われるように、言葉は言葉ほどではなく、表現は絵ほどではない。これがどの JavaScript を指しているのかをよりよく理解するには?画像を使って説明しましょう:
上の図を「JavaScript この決定ツリー」(非厳密モード) と呼びます。以下は例を使用して、この図がこれを判断するのにどのように役立つかを示しています:
var point = { x : 0, y : 0, moveTo : function(x, y) { this.x = this.x + x; this.y = this.y + y; } }; //决策树解释:point.moveTo(1,1)函数不是new进行调用,进入否决策, //是用dot(.)进行调用,则指向.moveTo之前的调用对象,即point point.moveTo(1,1); //this 绑定到当前对象,即point对象
「JavaScript this 決定木」の point.moveTo() 関数の決定処理は以下のとおりです。
1) point.moveTo 関数は new を使用して呼び出されていますか?これは明らかに当てはまりません。「いいえ」分岐に進みます。つまり、関数は dot(.) で呼び出されますか? ;
2) point.moveTo 関数は dot(.) を使用して呼び出されます。つまり、「yes」分岐に入ります。つまり、ここでは point.moveTo 内の前のオブジェクト ポイントを指します。
これが point.moveTo 関数内で何を指すのかを示す分析図は次のとおりです。
別の例として、次のコードを見てください:
function func(x) { this.x = x; } func(5); //this是全局对象window,x为全局变量 //决策树解析:func()函数是用new进行调用的么?为否,进入func()函数是用dot进行调用的么?为否,则 this指向全局对象window x;//x => 5
JavaScript this 決定木」で func() 関数が意思決定を行うプロセスは次のとおりです。 1) func(5) 関数は new を使用して呼び出されていますか?これは明らかに当てはまりません。「いいえ」分岐に進みます。つまり、関数は dot(.) で呼び出されますか? ;
2) func(5) 関数は dot(.) で呼び出されません。つまり、「No」分岐に入ります。つまり、ここでは this がグローバル変数 window を指しており、this.x は実際には window です。 .x;
これが func 関数内で何を指すのかを示す分析図は次のとおりです。
関数としての直接呼び出しについて、複雑な例を見てみましょう:
var point = { x : 0, y : 0, moveTo : function(x, y) { // 内部函数 var moveX = function(x) { this.x = x;//this 指向什么?window }; // 内部函数 var moveY = function(y) { this.y = y;//this 指向什么?window }; moveX(x); moveY(y); } }; point.moveTo(1,1); point.x; //=>0 point.y; //=>0 x; //=>1 y; //=>1point.moveTo(1,1) 関数は、実際には moveX() 関数と moveY() 関数を内部で呼び出します。 moveX() 関数内の this は、「
」で決定されます。プロセスは次のようになります: 1) moveX(1) 関数は new を使用して呼び出されていますか?これは明らかに当てはまりません。「いいえ」分岐に進みます。つまり、関数は dot(.) で呼び出されますか? ;
2) moveX(1) 関数は dot(.) で呼び出されません。つまり、「No」分岐に入ります。つまり、ここでは this がグローバル変数 window を指しており、this.x は実際には window です。 .x;
コンストラクターを呼び出す例を見てみましょう:
function Point(x,y){ this.x = x; // this ? this.y = y; // this ? } var np=new Point(1,1); np.x;//1 var p=Point(2,2); p.x;//error, p是一个空对象undefined window.x;//2「
」の var np=new Point(1,1) でこれを判断する Point(1,1) 関数の処理は次のとおりです。 1) var np=new Point(1,1) への呼び出しは new を使用していますか?これは明らかに「yes」分岐に入る、つまり np を指します。 2) this.x=1、つまり np.x=1;
「JavaScript この決定ツリー
」の var p= Point(2,2) でこれを決定する Point(2,2) 関数のプロセスは次のとおりです。1) var p= Point(2,2) への呼び出しは new を使用していますか?これは明らかに当てはまりません。「いいえ」分岐に進みます。つまり、関数は dot(.) で呼び出されますか? ;
2) Point(2,2) 関数は dot(.) で呼び出されませんか?判定が「いいえ」の場合、「いいえ」分岐に入ります。つまり、ここでは this がグローバル変数 window を指しており、this.x は実際には window.x; です。
3) this.x=2 は window.x=2 を意味します。最後に、call と apply を使用して呼び出される関数の例を見てみましょう。
「JavaScript this 決定木」の p1.moveTo.apply(p2,[10,10]) 関数の処理は以下のとおりです。
apply と call の 2 つのメソッドは、関数実行のコンテキスト、つまりこれにバインドされているオブジェクトを切り替えることができることが非常に強力であることがわかります。 p1.moveTo.apply(p2,[10,10]) は実際には p2.moveTo(10,10) です。 p2.moveTo(10,10) は次のように解釈できます:
1) p2.moveTo(10,10) 関数は new を使用して呼び出されていますか?これは明らかに当てはまりません。「いいえ」分岐に進みます。つまり、関数は dot(.) で呼び出されますか? ;
2) p2.moveTo(10,10) 関数は dot(.) で呼び出されます。つまり、「yes」分岐に入ります。つまり、ここでは p2.moveTo( 内の前のオブジェクト p2 を指します) 10,10) なので、p2.x=10;
JavaScript 関数の実行環境のプロセスについては、IBM Developerworks ドキュメント ライブラリに非常に優れた説明があります。その抜粋は次のとおりです。
「JavaScript の関数は、通常の関数として実行することも、オブジェクトのメソッドとして実行することもできます。これが、これほど豊かな意味を持つ主な理由です。関数が実行されると、実行環境 (ExecutionContext) が作成され、関数のすべての動作は、この実行環境で行われます。JavaScript は、関数呼び出し時に渡されるパラメーターを含む引数変数を最初に作成し、それを初期化します。関数の仮パラメータ リストの場合、値は引数変数の対応する値です。引数変数に対応する値がない場合、仮パラメータは未定義に初期化されます。関数に内部関数が含まれている場合、これらの内部関数は初期化されます。そうでない場合は、初期化を続行します。この関数で定義されているローカル変数については、この時点で変数が未定義に初期化され、実行環境 (ExecutionContext) の後に関数が実行されるまで、その代入操作は実行されないことに注意してください。 ) が正常に作成されました。これは、JavaScript における変数の役割を理解する上で非常に重要です。スペースの観点から、このトピックについては説明しません。最後に、この変数に値を割り当てます。上で説明したように、関数呼び出しメソッド (この時点まで) が正常に作成され、関数が 1 行ずつ実行され、必要な変数に応じてこのグローバル オブジェクト、現在のオブジェクトなどに割り当てられます。先に構築した実行環境(ExecutionContext)”
から読み込みます。この段落を理解することは、JavaScript 関数を理解する上で非常に役立ちます。
上記は JavaScript の this キーワードについて詳しく説明したもので、一般に、テキストよりも画像の方が理解しやすいです。この記事が皆さんの学習に役立つことを願っています。