[JavaScript] This


まず、MDNドキュメントで定義されているthisを見てみましょう.
JavaScriptでは、関数内のこのキーワードの動作は他の言語とは少し異なります.さらに,厳格モードと非厳格モードの間にもいくつかの相違がある.
ほとんどの場合、thisの値は関数を呼び出す方法によって決まります.実行時に割り当てに設定することはできません.関数を呼び出すときに異なる場合があります.ES 5は、この値をどのように呼び出すかを考慮せずにbindメソッドを導入し、ES 2015は、このバインドを提供しない矢印関数(集合コンテキストのこの値を保持する)を追加した.
javascriptでは、thisの意味は呼び出されたことを示します.
したがって、何も指定せずにこの操作を呼び出すと、ブラウザ環境ではウィンドウがグローバルオブジェクトであるため、ウィンドウがこの操作になります.
console.log(this);

function tempFunc() {
  console.log(this);
}
window.tempFunc();

Classを使用して、サンプルを表示します。


カウンタがincreateを呼び出すため、これはカウンタになります.
class Counter {
  count = 0;
  increase = function () {
    console.log(this); // this: Counter
  };
}
const counter = new Counter();
counter.increase();

const、letに割り当てたら...?


呼び出し元をconstに割り当てると、未定義の呼び出し元が表示されます.

どうしてこんなことになったの?


元counterのincrementのthisはClass counterを指していました.
しかしcallerという変数が指定されたため、thisの情報が失われた.
letとconstとして宣言された変数はウィンドウに登録されていません.
呼び出し元はオブジェクトではないため、結果値は定義されていません.
class Counter {
  count = 0;
  increase = function () {
    console.log(this); // this: undefined
  };
}
const counter = new Counter();
const caller = counter.increase();
caller();

はっきり言えたら、


JavaScriptで関数を定義する場合、デフォルトではグローバルオブジェクトからアクセスできます.
function temp() { console.log('temp') }

window.temp();
ただし、constまたはletを使用して変数を宣言すると、ウィンドウに登録されません.
上のようにwindowtemp(); これは不可能です.

例外があればvarです


同様に例外事項も存在する.varです.
const、letとは異なり、varを使用して関数を登録すると、上のコードのようにウィンドウオブジェクトにアクセスできます.
varには多くの問題がある.護衛問題だけでなく(つまり、一番下で発表し、上に発表した問題).再定義された様々な問題が多く、varは使用できません.
ここにも問題が発見された.すなわちwindowでvarと定義されている関数にアクセスできます.
次のコードの例は、次のとおりです.
増分としてbobというオブジェクトのrunの関数を指定します.
これはBobになることがわかります.
runという関数はbobによって呼び出されるからです.
このように、この情報を他の場所に分配した瞬間に、本来の情報が失われる可能性があり危険です.
したがってbindを使用してオブジェクトと関数の関係をバインドします.
class Counter {
  count = 0;
  increase = function () {
    console.log(this); // this: Bob
  };
}
const counter = new Counter();
counter.increase();
const caller = counter.increase;
caller();

class Bob {}
const bob = new Bob();
bob.run = counter.increase;
bob.run();

bindを使え!

class Counter {
  count = 0;
  increase = function () {
    console.log(this); // this: Bob
  };
}
const counter = new Counter();
counter.increase();
const caller = counter.increase.bind(counter);
caller();

class Bob {}
const bob = new Bob();
bob.run = counter.increase;
bob.run();

いちいち縛るのがおっくうなら?


バインドする必要がなく、異なる方法を使用したい場合は.
クラスで関数を宣言するときにfunctionではなくarrow関数を使用する場合はbindを使用せずに接続できます.
つまり、スコフのこのコンテキストを維持します.
arrow関数自体にscopeが記憶されるため、その内容を維持するために(bind call apply)arrow関数構文を使用してこれらの関数を置き換えることができます.