コンテキストとthisの実行


Javascriptでは、混同されるたびにexecution contextとthisをまとめます.
これは、関数を呼び出すときに、その関数の所有者を表します.
つまり、「thisは実行コンテキストを指す」ということです.
Contextの意味は「文脈」です.Execution Context(실행컨텍스트)関数実行(呼び出し)時の脈絡といえる.
これは呼び出し関数を持つ所有者と見なすこともできる.
したがって,同じ関数でも呼び出し時の所有者が誰であるかによってthisの値が変化する.
let obj = {
  name: "objContext",
  printThis: function() {
    console.log(this);
  }
};

let obj2 = {
  name: "objContext2",
  printThis: obj.printThis
};

let printThis = obj.printThis;

// 소유자가 obj, this = obj
obj.printThis(); // obj

// 소유자가 obj2, this = obj2
obj2.printThis(); // obj2

// 소유자가 전역환경, this = window
printThis(); // widnow

// 소유자가 button element, this = btnElem
let btnElem = document.createElement("button");
btnElem.addEventListener("click", printThis);
btnElem.click(); // button element 
これをロック
前の内容をもう一度整理すれば.
これは、実行コンテキストを指す値です.
実行コンテキストは実行時に決定されるため、呼び出された時点に応じて値が動的に変更されます.
しかし、動的に変化するthis値を固定する方法はいくつかあります.
call, apply
これらはFunctionクラスの基本的な方法です.
固定するthisをパラメータに渡すことで、this値を固定して呼び出すことができます.
var obj = {
  name: "objContext",
  printThis: function() {
    console.log(this);
  }
};

obj.printThis() // {name: 'objContext', printThis: ƒ}
obj.printThis.call(this) // Window {0: global, …}
obj.printThis.apply(this) // Window {0: global, …}
2つの動作は似ていますが、パラメータを越える方法の違いがあります.func.call(thisArg[, arg1[, arg2[, ...]]]) func.apply(thisArg, [argsArray])bind
同様にFunctionクラスの基本的な方法です.
固定したいthisパラメータをパラメータに変換
違いは、callこれを固定して関数を呼び出し、applyこの固定した新しい関数を返します.
var obj = {
  name: "objContext",
  printThis: function() {
    console.log(this);
  }
};

var objPrintThis = obj.printThis.bind(obj);
var globalPrintThis = obj.printThis.bind(this);

// 별도의 호출이 필요하다.
objPrintThis() // {name: 'objContext', printThis: ƒ}
globalPrintThis() // Window {0: global, …}
コンストラクタcall, applyキーワードとともに呼び出される関数をコンストラクション関数と呼ぶ.
通常の関数とは異なり、newキーワードは特別なことをするので、これは固定されます.
コンストラクション関数を呼び出すと、次の手順に従います.
  • 新規キーワード生成新規オブジェクト空間
  • 生成されたオブジェクト空間とそれをバインド<-この過程でthisは固定される.
  • 生成したオブジェクトを返す
  • function test () { 
      console.log(this) 
    }
    
    test() // Window {0: global, window: Window, …}
    new test() // {}
    Arrow Function
    通常、bindキーワードを使用する関数宣言または関数式で定義された関数のthisは、実行コンテキストを指します.
    ただし、es 6からサポートされる矢印関数を使用してこの値を固定します.
    実際、Arrow Functionには固定ではなく、この値はありません.
    スキャンチェーンに沿って、ブモクフのthisに近づくしかありません.
    (scopeは実行コンテキストではなくディレクトリコンテキストに従います)
    集合コンテキスト
    実行時ではなく、関数定義時のコンテキスト
    let obj = {
      name: "objContext",
      printThis: () => {
        // this 값이 없다. 부모스코프(=부모의 렉시컬스코프)인 global을 this로 갖게된다.
        console.log(this); 
      }
    };
    
    let obj2 = {
      name: "objContext2",
      printThis: obj.printThis
    };
    
    let printThis = obj.printThis;
    
    let btnElem = document.createElement("button");
    btnElem.addEventListener("click", printThis);
    
    // 모두 window로 고정이 되었다.
    btnElem.click(); // Window {window: Window …}
    obj.printThis(); // Window {window: Window …}
    obj2.printThis(); // Window {window: Window …}
    printThis(); // Window {window: Window …}
    リファレンス
    https://poiemaweb.com/js-this
    https://www.youtube.com/watch?v=PAr92molMHU&list=PLuBMRNcyzsWxcnDdAmJWyWYXuExyP9aS1&index=6