1. このキーワードの役割
JavaScript のthis
キーワードは、外側の関数が呼び出される時点のオブジェクトを参照します。コンテキストが異なると、this
の指示が変わります。
グローバル コンテキストでは、this
グローバル オブジェクト (ブラウザーのwindow
オブジェクト、 global
Node.js のオブジェクト) を指します。
関数内で、this
関数を呼び出したオブジェクトへのポインター。関数がオブジェクトのメソッドを通じて呼び出された場合はそのオブジェクトthis
を指し、関数を通じて呼び出された場合はthis
グローバル オブジェクトを指します。
アロー関数では、this
親スコープから継承しますthis
。
クラスのコンストラクターで、new
キーワード、this
クラスは新しく作成されたオブジェクトを指します。
例えば:
class MyClass {
constructor() {
this.value = 42;
}
}
let obj = new MyClass();
console.log(obj.value); // 42
クラスのインスタンス メソッドの this はデフォルトでインスタンス自体を指し、クラス メソッドの this はデフォルトでクラス自体を指します。
例えば:
class MyClass {
value = 42;
printValue() {
console.log(this.value);
}
static printValue() {
console.log(this.value);
}
}
let obj = new MyClass();
obj.printValue(); // 42
MyClass.printValue(); // undefined
Object.create
メソッドを使用してオブジェクトを作成する
Object.create
メソッドを使用して作成された特別な呼び出し方法です。この場合、関数がオブジェクトのプロトタイプ チェーンで呼び出される場合は、オブジェクトthis
を。
例えば:
let baseObject = { value: 42 };
let obj = Object.create(baseObject);
function printValue() {
console.log(this.value);
}
printValue.call(obj); // 42
この場合、obj のプロトタイプ チェーンに value プロパティがあるため、printValue() メソッドが呼び出されるとき、これは obj オブジェクトを指します。
クラスでのアロー関数の使用
クラス内のアロー関数によって定義されたメソッド内の this ポインターはバインドされており、クラス自体ではなくクラスのインスタンスを指します。
例えば:
class MyClass {
value = 42;
printValue = () => {
console.log(this.value);
}
}
let obj = new MyClass();
obj.printValue(); // 42
アロー関数this
はthis
呼び出し時ではなく定義時に行われますthis
。したがって、クラスでアロー関数を使用すると、メソッドでのバインディングのbind
使用this
。
コンストラクターを呼び出すとき、new キーワードは使用されません。
この場合、これはグローバル オブジェクトを指します。この場合、新しいオブジェクトは作成されませんが、グローバル オブジェクトの状態は変更されます。
例えば:
class MyClass {
constructor() {
this.value = 42;
}
}
let obj = MyClass(); // without new keyword
console.log(obj); // undefined
console.log(value); // 42
したがって、コンストラクターを使用してオブジェクトを作成する場合は、必ず new キーワードを使用してコンストラクターを呼び出す必要があります。そうしないと、予期しない結果が生じる可能性があります。
コンストラクターを使用するときに呼び出す new キーワードの使用には特別な注意を払う必要があります。
オブジェクトのメソッドでアロー関数を使用すると、問題が指摘されます。
例えば:
let obj = {
value: 42,
printValue: () => {
console.log(this.value);
}
};
obj.printValue(); // undefined
この場合、obj オブジェクトの printValue メソッドでアロー関数が使用されており、アロー関数の this は、呼び出されたときの this ではなく、定義されたときに this を指します。この場合、アロー関数の this は定義時に this を指しているため、 this.value は obj オブジェクトの value ではなく undefined を指しています。
このような問題を解決するには、アロー関数の親スコープでこれを使用するか、通常の関数を使用して解決します。
例えば:
let obj = {
value: 42,
printValue: function(){
console.log(this.value);
}
};
obj.printValue(); // 42
また
let obj = {
value: 42,
printValue: () => {
console.log(obj.value);
}
};
obj.printValue(); // 42
オブジェクトのメソッドでアロー関数を使用すると問題が発生するため、特別な注意が必要です。これは、アロー関数または通常の関数の親スコープで this を使用することで解決できます。
つまり、JavaScript の this キーワードが指すコンテキストは関数の呼び出し方法に依存しており、さまざまなシナリオに応じて this の方向を変更するには適切な方法を選択する必要があります。
2. このコンテキストを変更する方法
call
のコンテキストは、、、apply
メソッドbind
によってthis
変更できます。
call
およびapply
メソッドを使用this
関数を指定したオブジェクトにポイントし、その関数をただちに実行できます。
call
メソッドの構文は次のとおりです。
functionName.call(thisArg, arg1, arg2, ...);
apply
メソッドの構文は次のとおりです。
functionName.apply(thisArg, [arg1, arg2, ...]);
bind
メソッドを使用すると、指定したオブジェクトを関数にthis
指すことますが、関数をすぐに実行するのではなく、将来実行できる新しい関数を返します。
let newFunc = functionName.bind(thisArg, arg1, arg2, ...);
例えば:
let obj = {value: 42};
function printValue() {
console.log(this.value);
}
printValue.call(obj); // 42
printValue.apply(obj); // 42
let boundFunc = printValue.bind(obj);
boundFunc(); // 42
つまり、call
, apply
,bind
メソッドを使用すると、関数内のthis
ポインター。