ホームページ  >  記事  >  ウェブフロントエンド  >  JavaScriptでのこのポインティングの詳細な説明

JavaScriptでのこのポインティングの詳細な説明

零下一度
零下一度オリジナル
2017-07-24 16:00:411301ブラウズ

JavaScript での this の指摘は、フロントエンドの同僚にとって常に悩みの種であり、面接のさまざまな質問の最初の選択肢でもあります。ここで、js での this の指摘をまとめます。まず、いくつかの概念を理解する必要があります:

1: デフォルトでは、グローバル変数は window オブジェクトの下にマウントされます

2: 一般に、これは呼び出し元を指します

3: es6 のアロー関数では、これは呼び出し元ではなく作成者を指します

4: call、apply、bind を通じて this のポインタを変更できます

詳しく分析してみましょう

1: 関数が呼び出されたとき

(非厳密モード)

const func = function () {
    console.log(this);
    const func2 = function () {
      console.log(this);
    };
    func2(); //Window
  };
  func(); //Window

(厳密モード)

'use strict'
  const func = function () {
    console.log(this);
    const func2 = function () {
      console.log(this);
    };
    func2(); //undefined
  };
  func(); //undefined

4 番目と最初の 2 つのルールを組み合わせる: func 関数はグローバルであり、デフォルトでは window オブジェクトの下にマウントされます。 window オブジェクトは出力されますが、厳密モードです。この下では、this がグローバル変数 window を指すことは許可されていないため、出力は未定義です (関数が直接呼び出された場合、func2 はデフォルトでグローバル window を指します。実際、これはJavaScript の設計上の欠陥です。正しい設計方法では、この 内部関数 をその外部関数に対応するオブジェクトにバインドする必要があります。この設計上の欠陥を回避するために、賢明な JavaScript プログラマーは変数置換の方法を考え出しました。慣例により、変数には通常 that という名前が付けられます (この方法については次に説明します)。

2: オブジェクトメソッドとして

const user = {

    userName: '小张',
    age: 18,
    selfIntroduction: function () {
      const str = '我的名字是:' + this.userName + ",年龄是:" + this.age;
      console.log(str);

      const loop = function () {
        console.log('我的名字是:' + this.userName + ",年龄是:" + this.age);
      };

      loop();   //我的名字是:undefined,年龄是:undefined

    }
  };

  user.selfIntroduction();  //我的名字是:小张,年龄是:18

最初のルールによれば、これは彼の呼び出し元を指します。したがって、self Introduction() メソッドの内部では、これは彼を指します。親オブジェクトは user であり、ループ メソッドが未定義を出力する理由は、上で述べた JavaScript の設計上の欠陥です。この場合、通常はこれを self Introduction() メソッドでキャッシュすることを選択します。

const user = {
    userName: '小张',
    age: 18,
    selfIntroduction: function () {
      const str = '我的名字是:' + this.userName + ",年龄是:" + this.age;
      console.log(str);

      const that=this;

      const loop = function () {
        console.log('我的名字是:' + that.userName + ",年龄是:" + that.age);
      };

      loop();   //我的名字是:小张,年龄是:18

    }
  };

  user.selfIntroduction();  //我的名字是:小张,年龄是:18

現時点では、ループのこのポイントが理想的です。

const user={

    userName:'小张',
    age:18,
    selfIntroduction:function(){
      const str='我的名字是:'+this.userName+",年龄是:"+this.age;
      console.log(str); 
    }
  };

  const other =user.selfIntroduction;
  other(); //我的名字是:undefined,年龄是:undefined

  const data={
    userName:'小李',
    age:19,
  };
  data.selfIntroduction=user.selfIntroduction;
  data.selfIntroduction(); //我的名字是:小李,年龄是:19

このコードを見ると、self Introduction() がグローバル変数 other に割り当てられ、other() メソッドがグローバル関数 window オブジェクトの下にマウントされています。したがって、出力は未定義です。 2 番目のコードは、username 属性と age 属性を含むデータ オブジェクトを宣言します。一般的に、これは data が self Introduction() 関数の呼び出し元であることを理解しています。とデータの古さが出力されます。

3: html のイベントとしてトリガーされます

<body>
  <p id="btn">点击我</p>
</body>
     const btn=document.getElementById(&#39;btn&#39;);
    btn.addEventListener(&#39;click&#39;,function () {
      console.log(this); //<p id="btn">点击我</p>
    })

この場合、実際には 2 番目のルールに従います。一般に、これは呼び出し元を指し、これはイベントのイベント ソースを指します。イベント。

4: 新しいキーワード (コンストラクター)


const fun=function(userName){
    this.userName=userName;
  }
  const user=new fun(&#39;郭德纲&#39;);  
  console.log(user.userName); //郭德纲

ここでは詳細は説明しません。そのため、userName はオブジェクトのインスタンスのユーザー プロパティになります。物体。

5:es6 (アロー関数)

const func1=()=>{
    console.log(this); 
  };
  func1(); //Window
const data={
    userName:&#39;校长&#39;,
    selfIntroduction:function(){
      console.log(this); //Object {userName: "校长", selfIntroduction: function}
      const func2=()=>{
        console.log(this); //Object {userName: "校长", selfIntroduction: function}
      }
      func2();
    }
  }
  data.selfIntroduction();

誰もが最初に述べた 3 番目のルールに注目しています。es6 のアロー関数では、これは呼び出し元ではなく作成者を指し、fun1 が作成されます。グローバル関数の下にあるので、 this はグローバルウィンドウを指し、 fun2 はオブジェクト data の下に作成され、 this はデータオブジェクトを指します。 したがって、 func2 関数内では、 this はデータオブジェクトを指します。 個人的には、この点が重要だと思います。 es6 の矢印関数は、上で述べた JavaScript の設計上の欠陥を反映しています (個人的な認識)。

6: this のポイントを変更する

3 つの関数 call、apply、bind は、関数の this のポイントを人為的に変更できます。ここでは 3 つの違いについては詳しく説明しません。今後、この3つの違いについてはブログで詳しく説明していきたいと思います。では、例として 1 つを取り上げてみましょう

const func=function(){
   console.log(this);
 }; 
 func(); //window
 func.apply({userName:"郭德纲"}); //Object {userName: "郭德纲"}

これら 3 つのメソッドは this のポインタを人為的に変更できます。違いは、call と apply がメソッドを this にバインドしてすぐに実行するのに対し、bind メソッドは実行可能な関数を返すことです。

これの多くは、冒頭で述べた 4 つのポイントに要約できます

1: グローバル変数はデフォルトで window オブジェクトの下にマウントされます

2: 通常の状況では、これは呼び出し元を指します

3: es6 アロー関数では、this は呼び出し元ではなく作成者を指します

4: call、apply、bind を通じて this のポイントを変更できます

以上がJavaScriptでのこのポインティングの詳細な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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