[JavaScript] This


状況次第だ
これは関数を呼び出すときに決定されるので、値はどのように呼び出すかによって異なります.
グローバルスペースのthis
グローバル空間では、グローバルオブジェクトを指します.ブラウザ環境では、グローバルオブジェクトはウィンドウ、ノードです.js環境ではglobalです.
// 브라우저
console.log(this === window); //true 

// Node.js
console.log(this === global); //true 
グローバル変数を宣言すると、JavaScriptエンジンはグローバルオブジェクトのプロパティに割り当てます.
var a = 1;
console.log(a); // 1
console.log(window.a); // 1
console.log(this.a); // 1
ウィンドウaそしてこれ.aで1を出力するのは、JavaScriptのすべての変数が特定のオブジェクトのpropertyとして動作するためです.特定のオブジェクトは、実行コンテキストのLexicalEnvironmentです.コンテキスト収集変数を実行し、L.Eのpropertyとして保存します.次に変数を呼び出し、L.Eをクエリーして一致するプロパティ値を返します.L.Eはグローバルコンテキストでグローバルオブジェクトを参照します.
var a = 1;
widow.b = 2;
console.log(a, window.a, this.a); // 1 1 1
console.log(b, window.b, this.b); // 2 2 2
したがって、変数をvarとして宣言するよりも、windowのpropertyに直接割り当てるほうが、varとして宣言するのと同じように動作します.ただし、[削除](Delete)コマンドは、グローバル変数宣言とグローバルオブジェクトの構成割り当てに違いがあります.
var a = 1;
delete window.a; // false
console.log(a, window.a, this.a); // 1 1 1

var b = 2;
delete window.b; // false
console.log(a, window.a, this.a); // 2 2 2

window.c = 3;
delete window.c; // true
console.log(c, window.c, this.c); 
// Uncaught ReferenceError: c is not defined

window.d = 4;
delete window.d; // true
console.log(b, window.b, this.b); 
// Uncaught ReferenceError: b is not defined
この例では、グローバルオブジェクトのプロパティとして指定すると削除されますが、グローバル変数として宣言すると削除されません.なぜなら、JavaScriptエンジンは、グローバル変数を宣言すると自動的にグローバルオブジェクトのプロパティとして指定し、設定可能なプロパティ(変更可能および削除可能)をfalseとして定義するからです.
メソッドとして呼び出す場合、メソッド内部のthis
関数を実行する最も一般的な方法は、関数呼び出しとメソッド呼び出しとして使用され、両者を区別する方法は独立しています.関数自体は独立した機能を実行し、メソッドは呼び出したターゲットオブジェクトに関連する操作を実行します.JAvascriptは、状況に応じてキーワードに異なる値を付与して実現する.
var func = funtion (x) {
  console.log(this, x);
};
func(1); // Window {...} 1

var obj = {
  method: func
};
obj.method(2) // { method: f } 2
オブジェクトに関数を割り当てるプロパティはメソッドではなく、オブジェクトメソッドとして呼び出された関数のみをメソッド操作します.そうしないと、関数として操作されます.
var obj = {
  method: function (x) { console.log(this, x); }
};
obj.method(1); // { method: f } 1
obj['method'](2); // { method: f } 2
関数としての呼び出しとメソッドとしての呼び出しを区別する方法は,関数の前にオブジェクトと点記号(.)を用いる.かっこ([])で区別できます.
var obj = {
  methodA: function () { console.log(this); },
  inner: {
    methodB: funtion () { console.log(this); }
  }
};
obj.methodA(); // { methodA: f, inner: {...} } ( === obj)
obj['method']['merhodB'](); // { methodB: f } ( === obj.inner)
これには、呼び出しボディに関する情報が含まれます.メソッドで関数を呼び出すと、呼び出し元は関数名の前のオブジェクトになります.
関数として呼び出されたときの関数内部のthis
関数として関数を呼び出す場合は、thisは指定されません.ただし、実行コンテキストがアクティブ化されている間にthisが指定されていない場合、thisはグローバルオブジェクトを表示します.したがって、関数のthisはグローバルオブジェクトを指します.
var obj1 = {
  outer: function () {
    console.log(this);
    var innerFunc = function () {
      console.log(this);
    };
    innerFunc(); // 전역객체(window)
    
    var obj2 = {
      innerMethod: innerFunc,
    };
    obj2.innerMethod(); // obj2
  },
};
obj1.outer(); // obj1
以上の例から,thisが関数を実行する際の環境(メソッド内部か関数内部かなど)は重要ではなく,関数として実行するかメソッドとして実行するかによって決定されることが分かる.
var obj = {
  outer: function () {
    console.log(this);
    var innerFunc1 = function () {
      console.log(this);
    };
    innerFunc1(); // 전역객체(window)

    var self = this;
    var innerFunc2 = function () {
      console.log(self); 
    };
    innerFunc2(); // obj
  },
};
obj.outer();
外部ミラー名selfの変数に格納すると、innerFunc 2関数が呼び出されても、selfはオブジェクトobjを出力します.これにより、内部関数でthisを迂回することができます.
var obj = {
  outer: function () {
    console.log(this); // { outer: f } ojb
    var innerFunc = () => {
      console.log(this);
    };
    innerFunc(); // { outer: f } ojb
  }
};
obj.outer();
ES 6で導入された矢印関数(arrow function)を使用すると、実行コンテキストを作成するときにバインド・プロシージャ自体を除外でき、親のプロシージャを使用できます.
var Cat = funtion (name, age) {
  this.bark = '야옹';
  this.name = name;
  this.age = age;
};
var choco = new Cat('초코', 7);
var nabi = new Cat('나비', 5);
console.log(choco, nabi);
// Cat { bark: '야옹', name: '초코', age: 7 }
// Cat { bark: '야옹', name: 나비', age: 5 }
コンストラクション関数は、共通のプロパティを持つオブジェクトを作成するために使用されます.newコマンドで関数を呼び出すと、JavaScriptはコンストラクション関数として動作します.コンストラクション関数を呼び出すと、コンストラクション関数を参照するprototype propertyのprotoというpropertyというオブジェクトが作成され、予め用意された共通属性と個性がオブジェクトに付与されます(this).
これを明示的にバインドします.
コールメソッド
Funtion.protoype.call(thisArg[, arg1[, arg2[, ...]]])
callメソッドは,メソッド呼び出しの主体である関数を直ちに実行するコマンドである.callメソッドの最初のフェースパラメータをthisにバインドする場合は、任意のオブジェクトをthisとして指定できます.
var obj = {
  a: 1,
  method: function (x, y) {
    console.log(this.a, x, y);
  }
};

obj.method(2, 3); // 1 2 3
obj.method.call({ a: 4 }, 5, 6); // 4 5 6
メソッドは、callメソッドを使用して任意のオブジェクトをthisとして指定することもできます.
適用方法
Funtion.prototype.apply(thisArg[, argsArray])
var func = function (a, b, c) {
  console.log(this, a, b, c);
};
func.apply({x: 1}, [4, 5, 6]); // { x: 1 } 4 5 6

var obj = {
  a: 1,
  method: function (x, y) {
    console.log(this.a, x, y);
  }
};
obj.method.apply({ a: 4 }, [5, 6]); // 4 5 6
applyメソッドはcallメソッドと同じ機能ですが、2番目のパラメータを配列として受け入れ、その配列の要素を呼び出す関数のパラメータとして指定します.
bindメソッド
Funtion.prototype.bind(thisArg[, arg1[, arg2[, ...]]])
callと似ていますが、すぐに呼び出すのではなく、渡されたthisとパラメータに基づいて新しい関数を返す方法です.
var func = function (a, b, c, d) {
  console.log(this, a, b, c, d);
};
func(1, 2, 3, 4); // Window{ ... } 1 2 3 4

var bindFunc1 = func.bind({ x: 1});
bindFunc1(5, 6, 7, 8); // { x: 1 } 5 6 7 8

var bindFunc2 = func.bind({ x: 1}, 4, 5);
bindFunc1(6, 7); // { x: 1 } 4 5 6 7
bindFunc1(8, 9); // { x: 1 } 4 5 8 9
上記の例では、thisが{x:1}として指定され、bindに渡されるパラメータの4,5が新しい関数に含まれていることがわかります.
var func = function (a, b, c, d) {
  console.log(this, a, b, c, d);
};
var bindFunc = func.bind({ x: 1 }, 4, 5);
console.log(func.name); // func
console.log(bindFunc.name); // bound func
bindメソッドを適用して新しい関数にname propertyに動詞bindの手動bound接頭辞を付ける.これにより、呼び出しやアプリケーションよりもトレースコードが容易になります.
矢印関数の例外
矢印関数は、コンテキスト作成を実行するときにthisをバインドするプロセスを含まないため、この関数の内部にはthisはまったくありません.アクセスする場合はsco茨チェーンの最近のthisにアクセスします.