[Javascript] this

18661 ワード

1.このキーワード


なぜこのキーワードが必要なのか

  • 動作を表す方法は、その属するオブジェクトの状態、すなわちPropertyを参照して変更できる必要があります.メソッドが属するオブジェクトのプロパティを参照する場合は、まずそのオブジェクトを指す識別子を参照する必要があります.
  • これは、所属するオブジェクトまたは作成するインスタンスを指す自己参照変数です.これにより、オブジェクトまたは作成するインスタンスに属するプロシージャまたはメソッドを参照できます.
    JavaScriptのthisは、関数呼び出しに基づいてthisにバインドされる値、すなわちthisバインドを動的に決定します.

    2.関数の呼び出しとバインド


    このバインド(この値にバインドされる)は、関数が呼び出される方法(すなわち、関数がどのように呼び出されるか)によって動的に決定されます.
  • Lexicallscopeとこのバインドの決定時間は異なります.
    関数の親スキャンを決定する方法は、関数定義が評価され、関数オブジェクトの作成時に親スキャンが決定されます.ただし、このバインドは関数呼び出し時に決定されます.
  • 関数の呼び出し方法
    1.一般関数の呼び出し
    2.呼び出し方法
    3.コンストラクタの呼び出し
    4. Function.prototype.apply/call/bindメソッドによる間接呼び出し
    // this 바인딩은 함수 호출 방식에 따라 동적으로 결정된다.
    const foo = function () {
      console.dir(this);
    };
    
    // 동일한 함수도 다양한 방식으로 호출할 수 있다.
    
    // 1. 일반 함수 호출
    // foo 함수를 일반적인 방식으로 호출
    // foo 함수 내부의 this는 전역 객체 window를 가리킨다.
    foo(); // window
    
    // 2. 메서드 호출
    // foo 함수를 프로퍼티 값으로 할당하여 호출
    // foo 함수 내부의 this는 메서드를 호출한 객체 obj를 가리킨다.
    const obj = { foo };
    obj.foo(); // obj
    
    // 3. 생성자 함수 호출
    // foo 함수를 new 연산자와 함께 생성자 함수로 호출
    // foo 함수 내부의 this는 생성자 함수가 생성한 인스턴스를 가리킨다.
    new foo(); // foo {}
    
    // 4. Function.prototype.apply/call/bind 메서드에 의한 간접 호출
    // foo 함수 내부의 this는 인수에 의해 결정된다.
    const bar = { name: 'bar' };
    
    foo.call(bar);   // bar
    foo.apply(bar);  // bar
    foo.bind(bar)(); // bar

    2.1一般関数の呼び出し


    デフォルトでは、thisはグローバルオブジェクトをバインドします.
    function foo() {
      console.log("foo's this: ", this);  // window
      function bar() {
        console.log("bar's this: ", this); // window
      }
      bar();
    }
    foo();
    通常の関数として関数を呼び出すと、thisでグローバルオブジェクトがバインドされます.

    2.2メソッド呼び出し


    メソッド内部のthisは、メソッドを呼び出すオブジェクト、すなわちメソッドを呼び出すときのメソッド名の前のピリオド(.)先に説明したオブジェクトをバインドします.メソッドが持つオブジェクトではなく、メソッド内部のthisがメソッドを呼び出すオブジェクトにバインドされていることに注意してください.
    const person = {
      name: 'Lee',
      getName() {
        // 메서드 내부의 this는 메서드를 호출한 객체에 바인딩된다.
        return this.name;
      }
    };
    
    // 메서드 getName을 호출한 객체는 person이다.
    console.log(person.getName()); // Lee
    上記の例のgetNameメソッドは、personオブジェクトのメソッドとして定義されています.方法はプログラムにバインドされた関数です.すなわち,personオブジェクトのgetName Propertyが指す関数オブジェクトは,personオブジェクトに含まれるのではなく,独立して存在する独立したオブジェクトである.getName Propertyは、関数オブジェクトのみを指します.

    2.3構造関数の呼び出し


    コンストラクション関数の内部にあるthisでは、コンストラクション関数は作成するインスタンスをバインドします.
    // 생성자 함수
    function Circle(radius) {
      // 생성자 함수 내부의 this는 생성자 함수가 생성할 인스턴스를 가리킨다.
      this.radius = radius;
      this.getDiameter = function () {
        return 2 * this.radius;
      };
    }
    
    // 반지름이 5인 Circle 객체를 생성
    const circle1 = new Circle(5);
    // 반지름이 10인 Circle 객체를 생성
    const circle2 = new Circle(10);
    
    console.log(circle1.getDiameter()); // 10
    console.log(circle2.getDiameter()); // 20

    2.4 Function.prototype.apply/call/bindメソッドによる間接呼び出し


    アプリ、call、bindメソッドはFunctionです.プロトタイプの方法.すなわち、これらの方法は、すべての関数によって継承されて使用することができる.
    apply、callメソッドは、このメソッドを使用するオブジェクトとパラメータのリストをパラメータとして渡し、関数を呼び出します.
    function getThisBinding() {
      return this;
    }
    
    // this로 사용할 객체
    const thisArg = { a: 1 };
    
    console.log(getThisBinding()); // window
    
    // getThisBinding 함수를 호출하면서 인수로 전달한 객체를 getThisBinding 함수의 this에 바인딩한다.
    console.log(getThisBinding.apply(thisArg)); // {a: 1}
    console.log(getThisBinding.call(thisArg)); // {a: 1}
    apply,callメソッドの本質的な機能は呼び出し関数である.applyメソッドとcallメソッドは、関数を呼び出すときに最初の引数として渡される特定のオブジェクトに関数をバインドします.
    apply,callメソッドは,呼び出した関数にパラメータを渡す方法が異なり,その動作方式が同じにすぎない.
    function getThisBinding() {
      console.log(arguments);
      return this;
    }
    
    // this로 사용할 객체
    const thisArg = { a: 1 };
    
    // getThisBinding 함수를 호출하면서 인수로 전달한 객체를 getThisBinding 함수의 this에 바인딩한다.
    // apply 메서드는 호출할 함수의 인수를 배열로 묶어 전달한다.
    console.log(getThisBinding.apply(thisArg, [1, 2, 3]));
    // Arguments(3) [1, 2, 3, callee: ƒ, Symbol(Symbol.iterator): ƒ]
    // {a: 1}
    
    // call 메서드는 호출할 함수의 인수를 쉼표로 구분한 리스트 형식으로 전달한다.
    console.log(getThisBinding.call(thisArg, 1, 2, 3));
    // Arguments(3) [1, 2, 3, callee: ƒ, Symbol(Symbol.iterator): ƒ]
    // {a: 1}
    applyメソッドとcallメソッドとは異なり、bindメソッドは関数を呼び出さず、このメソッドとして使用されるオブジェクトのみを渡します.
    function getThisBinding() {
      return this;
    }
    
    // this로 사용할 객체
    const thisArg = { a: 1 };
    
    // bind 메서드는 첫 번째 인수로 전달한 thisArg로 this 바인딩이 교체된
    // getThisBinding 함수를 새롭게 생성해 반환한다.
    console.log(getThisBinding.bind(thisArg)); // getThisBinding
    // bind 메서드는 함수를 호출하지는 않으므로 명시적으로 호출해야 한다.
    console.log(getThisBinding.bind(thisArg)()); // {a: 1}

    リファレンス


    モダンjavascript deep dive
    https://github.com/wikibook/mjs/blob/master/22.md