ホームページ  >  記事  >  ウェブフロントエンド  >  JavaScriptのthisポインタサンプルコードの詳細説明

JavaScriptのthisポインタサンプルコードの詳細説明

黄舟
黄舟オリジナル
2017-03-10 15:13:43941ブラウズ

これは 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

apply または call

これら 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 サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。