これについてまとめた


これについてまとめた
Javaのようなオブジェクト向け言語のthisはクラス(インスタンス化されたオブジェクト)自身を表す.
JavaScriptは、関数呼び出しに基づいてtihsにバインドするオブジェクトを動的に決定します.関数を宣言する場合、thisにバインドするオブジェクトは静的に決定されるのではなく、関数を呼び出すときに関数をどのように呼び出すかに基づいてthisにバインドするオブジェクトを動的に決定します.
関数を呼び出す方法は次のとおりです.
呼び出し
  • 関数
  • メソッド呼び出し
  • 呼び出し
  • ジェネレータ関数
  • アプリケーション/コール/バインディングコール
  • 1.関数呼び出し
    グローバルオブジェクトは、ブラウザでwindowを表すすべてのオブジェクトの最上位オブジェクトです.
    this === window; // true
    グローバル範囲に宣言される関数は、グローバルオブジェクトのpropertyとしてアクセスできるグローバル変数の方法です.
    var gv = "Global variable";
    
    console.log(gv);
    console.log(window.gv);
    
    function foo() {
      console.log("invoked!");
    }
    window.foo();
    デフォルトでは、thisはグローバルオブジェクトにバインドされます.グローバル関数だけでなく、内部関数の場合、thisもグローバルオブジェクトにバインドされます.
    function foo() {
      console.log("foo's this: ", this); // window
      function bar() {
        console.log("bar's this: ", this); // window
      }
      bar();
    }
    foo();
    内部関数の場合、thiswindowであってもよい.
    オブジェクトの関数(すなわちメソッド)が呼び出されると、メソッドのthisは、メソッドをモデルとするオブジェクトを参照する.
    したがって、functionのうちthisobjを指す.
    var value = 1;
    
    var obj = {
      value: 100,
      foo: function () {
        console.log("foo's this: ", this); // obj
        console.log("foo's this.value: ", this.value); // 100
        function bar() {
          console.log("bar's this: ", this); // window
          console.log("bar's this.value: ", this.value); // 1
        }
        bar();
      },
    };
    
    obj.foo();
    コールバック関数の場合、thisもグローバルオブジェクトにバインドされます.
    var value = 1;
    
    var obj = {
      value: 100,
      foo: function () {
        setTimeout(function () {
          console.log("callback's this: ", this); // window
          console.log("callback's this.value: ", this.value); // 1
        }, 100);
      },
    };
    
    obj.foo();
    内部関数は、一般的な関数、メソッド、およびコールバック関数で宣言された場所にかかわらず、グローバルオブジェクトthisにバインドされます.
    内部関数のthisがグローバルオブジェクトを参照しないようにするにはどうすればいいですか?
    次のコードを見て
    var value = 1;
    
    var obj = {
      value: 100,
      foo: function () {
        var that = this; // Workaround : this === obj
    
        console.log("foo's this: ", this); // obj
        console.log("foo's this.value: ", this.value); // 100
        function bar() {
          console.log("bar's this: ", this); // window
          console.log("bar's this.value: ", this.value); // 1
    
          console.log("bar's that: ", that); // obj
          console.log("bar's that.value: ", that.value); // 100
        }
        bar();
      },
    };
    
    obj.foo();
    objを指すthisは、that変数に格納され、その後、内部関数においてthatが使用される.applycallを使用してもよい.
    2.呼び出し方法
    メソッドが呼び出されると、そのメソッドを呼び出すオブジェクトにバインドされます.
    function foo() {
      this.check = function () {
        console.log("this is", this);
      };
    }
    
    var f = new foo();
    f.check(); // this is foo {check: ƒ}
    3.コンストラクタの呼び出し
    JavaScriptのコンストラクション関数は、オブジェクトの作成に役立ちます.既存の関数にnew演算子を加えて呼び出すと、この関数はコンストラクション関数として動作します.
    一般関数にnew演算子呼び出しを加えてもコンストラクション関数のように動作するため、一般コンストラクション関数は最初のアルファベットで大文字になります.
    コンストラクション関数によって生成されたオブジェクトは、thisにバインドされます.
    function Person(name) {
      this.name = name;
    }
    
    var kim = new Person("kim");
    
    console.log(kim.name); // {name: kim}
    ただし、newのキーワードを削除すると、コンストラクション関数は使用されません.
    var kim = Person("kim");
    
    console.log(kim.name); // undefined
    4.apply/call/bindを呼び出すthisにバインドされたオブジェクトは、関数呼び出しモードによってJavaScriptエンジンによってデフォルトで決定されます.この方法に加えて、thisを特定のオブジェクトに明確にバインドする方法は、applyおよびcallである.applycallの両方がFunction.prototypeオブジェクトである方法
  • Function.prototype.call()
  • func.call(thisArg[, arg1[, arg2[, ...]]])
    
    // thisArg : 함수 내부의 this에 바인딩할 객체
    // arg1, arg2, ... : 함수에 전달할 인자들
    次のコードを見て
    var person1 = {
      name: "Jo",
    };
    
    var person2 = {
      name: "Kim",
      study: function () {
        console.log(this.name + "이/가 공부를 하고 있습니다.");
      },
    };
    
    person2.study(); // Kim이/가 공부를 하고 있습니다.
    
    // call()
    person2.study.call(person1); // Jo이/가 공부를 하고 있습니다.
    person2.study.call(person1);は、person2の関数をコードで呼び出すが、callの関数の最初のパラメータにはperson1が加えられ、thisperson1を指す.
  • Function.prototype.apply()
  • func.apply(thisArg, [argsArray]);
    
    // thisArg: 함수 내부의 this에 바인딩할 객체
    // argsArray: 함수에 전달할 argument의 배열
    applycallと同じであり、2番目のパラメータをアレイ形式(アレイまたは類似のアレイオブジェクト)として加えた違いを除く.
    5.矢印関数のthis
    矢印関数のthisは、一般的な関数のthisとは異なります.
    関数を宣言すると、矢印関数は、この関数にバインドするオブジェクトを静的に決定します.通常の関数とは異なり、矢印関数のthisは常に親scopeのthisを指します.これをLexicalisといいます.
    function Person() {
      this.age = 0;
    
      setTimeout(() => {
        this.age++; // this는 상위 스코프인 Person 객체를 참조
        console.log(this.age);
      }, 1000);
    }
    
    Person(); // 1
    6.参考
    https://poiemaweb.com/js-this
    https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/this