ホームページ > 記事 > ウェブフロントエンド > JavaScriptのthisポインタサンプルコードの詳細説明
これは 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)//this 绑定到当前对象,即 point 对象
ここで強調しておきたいのは、関数の定義時ではなく、関数の実行時に対応する値を取得するということです。オブジェクトのメソッド呼び出しであっても、メソッドの関数属性を関数名という形で別のスコープに渡すと、そのポインタが変更されます。例を挙げましょう:
rreee以上です。ここはややこしいところかもしれません。
このとき、関数はグローバルオブジェクトにバインドされて直接呼び出すこともできます。
var a = { aa : 0, bb : 0, fun : function(x,y){ this.aa = this.aa + x; this.bb = this.bb + y; } }; var aa = 1; var b = { aa:0, bb:0, fun : function(){return this.aa;} } a.fun(3,2); document.write(a.aa);//3,this指向对象本身 document.write(b.fun());//0,this指向对象本身 (function(aa){//注意传入的是函数,而不是函数执行的结果 var c = aa(); document.write(c);//1 , 由于fun在该处执行,导致this不再指向对象本身,而是这里的window })(b.fun);
しかし、これはいくつかの問題を引き起こします。つまり、関数内で定義された関数の場合、これはグローバルな世界も指すことになり、これは私たちが望んでいることとはまったく逆です。コードは次のとおりです:
var x = 1; function test(){ this.x = 0; } test(); alert(x); //0
必要な動きの効果が完了していないだけでなく、さらに 2 つのグローバル変数があることがわかります。では、どうすれば解決できるでしょうか?関数内で関数を入力するときにこれを変数に保存し、その変数を使用するだけです。コードは次のとおりです:
var point = { x : 0, y : 0, moveTo : function(x, y) { // 内部函数 var moveX = function(x) { this.x = x;//this 绑定到了全局 }; // 内部函数 var moveY = function(y) { this.y = y;//this 绑定到了全局 }; moveX(x); moveY(y); } }; point.moveTo(1, 1); point.x; //==>0 point.y; //==>0 x; //==>1 y; //==>1
JavaScript で独自のコンストラクターを作成する場合、これを使用して新しく作成されたオブジェクトを指すことができます。これにより、関数内の this がグローバル世界を指すことがなくなります。
var point = { x : 0, y : 0, moveTo : function(x, y) { var that = this; // 内部函数 var moveX = function(x) { that.x = x; }; // 内部函数 var moveY = function(y) { that.y = y; } moveX(x); moveY(y); } }; point.moveTo(1, 1); point.x; //==>1 point.y; //==>1
これら 2 つのメソッドは、関数実行のコンテキストを切り替えることができます。つまり、これにバインドされているオブジェクトを変更します。 apply と call は似ていますが、パラメータを渡すときの 1 つの要件は配列であり、もう 1 つの要件はそれらが別々に渡されることです。そこで例として apply を取り上げます:
var x = 2; function test(){ this.x = 1; } var o = new test(); alert(x); //2
通常、オブジェクト内のメソッドにアクセスすると、これがオブジェクトを指していることがわかります。 apply を使用した後、apply にパラメーターがない場合、this の現在のオブジェクトはグローバル オブジェクトになります。 apply にパラメーターがある場合、this の現在のオブジェクトはパラメーターになります。
ここで追加すべきことの 1 つは、次世代 JavaScript 標準 ES6 の arrow 関数の this は、関数が定義されたときではなく、常に this を指すということです。実行されました。例を通して理解しましょう:
<pre name="code" class="html">var name = "window"; var someone = { name: "Bob", showName: function(){ alert(this.name); } }; var other = { name: "Tom" }; someone.showName(); //Bob someone.showName.apply(); //window someone.showName.apply(other); //Tom
this のポインタが o からグローバルに変わるため、上記のコードはエラーを引き起こします。上記のコードを次のように変更する必要があります:
var o = { x : 1, func : function() { console.log(this.x) }, test : function() { setTimeout(function() { this.func(); }, 100); } }; o.test(); // TypeError : this.func is not a function
これを事前に外部に保存しておいたものを使用してください。ここで arrow 関数を使用できます。先ほど述べたように、arrow 関数の this は、関数が実行されるときではなく、関数が定義されるときに常に this を指します。したがって、上記のコードを次のように変更します。
var o = { x : 1, func : function() { console.log(this.x) }, test : function() { var _this = this; setTimeout(function() { _this.func(); }, 100); } }; o.test();今回は、this が o を指しています。また、注意する必要があるのは、これが指すオブジェクトを変更しないことです。ただし、アロー関数では無効です。
var o = { x : 1, func : function() { console.log(this.x) }, test : function() { setTimeout(() => { this.func() }, 100); } }; o.test();このようにして、さまざまな状況におけるこのバインディング オブジェクトの違いを理解することができます。
以上がJavaScriptのthisポインタサンプルコードの詳細説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。