JSのthis
私のようにjavaで符号化してjsに移行し始めた人は、この面で大きな混乱に直面します.javaはインスタンスのメンバーとして機能し、関数を構築する際にグローバルとして使用することができますが、jsは関数概念として広く使用されています.
jsのthisは、関数を呼び出すときの関数の呼び出し方法によって、その関数にバインドされるオブジェクトを動的に決定します.
1.(デフォルト)関数呼び出し時
jsのthisは、関数を呼び出すときの関数の呼び出し方法によって、その関数にバインドされるオブジェクトを動的に決定します.
1.(デフォルト)関数呼び出し時
デフォルトでは、thisはグローバルオブジェクトにバインドされます.
通常の関数だけでなく、内部関数とコールバック関数もこの関数を使用してグローバルオブジェクトにバインドされます。
すなわち、関数がメソッドフォーマットでない場合(=オブジェクトのpropertyとして定義されていない場合)
ウィンドウにバインドします.function foo() {
console.log("foo's this: ", this); // window
function bar() {
console.log("bar's this: ", this); // window
}
bar();
}
foo();
一般関数foo()のthisはjsの基本グローバルオブジェクトwindowにバインドされます.
bar()もwindowにバインドされています.あるいは、私のようにグローバルオブジェクト面関数もオブジェクトnifoo()にバインドすべきではないでしょうか.そう思う人もいるかもしれませんが、ここでいうグローバルオブジェクトでは、親関数をグローバルオブジェクトと見なしていないようです.以下に示すように、オブジェクトでpropertyとして定義された関数!すなわち、メソッド形式で定義された関数では、ウィンドウではなくグローバルオブジェクトが親として表されます.var value = 1;
var obj = {
value: 100,
foo: function() {
console.log("foo's this: ", this); // obj
console.log("foo's this.value: ", this.value); // 100
function bar() {
console.log("bar's this: ", this); // window
console.log("bar's this.value: ", this.value); // 1
}
bar();
}
};
obj.foo();
上の最初のthisが属する匿名関数を通常の関数として呼び出します!良いのではなく、方法で呼び出します!いいですよ.メソッドは通常,クラス内のメンバーに属する関数をメソッドと総称する概念である.したがって、メソッドとして呼び出されると、thisが指すグローバルはウィンドウではなく、オブジェクトobjになります.
したがって、上記のように、最初のthisはobjを指し、3番目のthisは関数の関数である内部関数であるため、内部関数のグローバルオブジェクトはwindowのままである.
(関数の関数の場合、グローバルオブジェクトはwindowです.関数のプロセスで関数が定義されている場合、グローバルオブジェクトはwindowからその属するオブジェクトに変更されます.)
もう一度深化すれば.
3行目からlet test1
をやりました.したがってAの場合はlet test1
がなければ,本来はグローバルオブジェクトobj
,objを指す.fooはpropertyメソッドとしてtest 1に属し、最終的なグローバルオブジェクトはlet test1
である.
B、Cのグローバルオブジェクトはもちろんwindowです.
すなわち,関数がオブジェクト内部の属性にバインドされている場合にのみ(これをメソッドフォーマットと呼ぶようになる).グローバルオブジェクトがwindow=>何になるかに注意してください.そのため、コールバック関数、内部関数、propertyに属さない一般的な関数であれば、windowを指します.
上記の方法に加えて、JavaScriptはpoemawebと呼ばれるapply、call、bindメソッドを明示的にバインドすることができる.comに出てきた
apply、call、bindは使えますが、bindだけを勉強しました.下線のbindはbar함수에서 this를 사용할땐 무조건 obj를 가르키게 해!
という意味で、つまりバインドします.
後で(1,2)関数bind(obj)を直ちに実行するように設定し、関数を直ちに呼び出したい場合bar(1,2)使いにくいので(1,2)に短縮して使います.
初心者の概念説明ページでこのようにすぐに関数などを使って説明しないと、親切な本ではありません.
2.呼び出し方法
前に説明しました.オブジェクトプロファイルとして登録されている関数(メソッド呼び出しフォーマット)はthisによって同じグローバルオブジェクトを指します.この場合、グローバルオブジェクトはウィンドウから他のオブジェクトに変更されます.
上のobj 1sayName()のこれはobj 1を表します.
上のobj 2sayName()のこれはobj 2を表します.
プロトタイプオブジェクトの内部で使用されるthisも、通常のメソッドのようにメソッドを呼び出すオブジェクトにバインドされます.
次はgetNameのthisがメソッドgetNameを呼び出すオブジェクトにバインドされています:me.
meはPerson()という関数に「Lee」パラメータを付けた例である.すなわち、関数Person(name){は新しいインスタンスであるため、関数Person(name){はjavaと同様であり、内部のthisは基本的にPersonを指し、インスタンスが作成されるとmeインスタンスオブジェクトを示す.
つまりPerson(‘Lee’)の実例が生まれた.nameは「Lee」の値をインスタンスのグローバル変数nameの値に伝播しますか?出力me.getName()
なら5行目のPersonprototype.getName関数のthis.nameは先ほど伝播したname値を受け入れ,Leeを出力する.
つまり、プロトタイプとして定義されたオブジェクトもメソッドであるため、プロトタイプを使用してバンドルされた親グローバルオブジェクトを指します.
例外:矢印関数定義メソッドを使用すると、矢印関数のthisはコンテキストwindowを指します.したがって、メソッドを定義する際に矢印関数を使用することは避けてください.// Bad
const person = {
name: 'Lee',
sayHi: () => console.log(`Hi ${this.name}`)
};
person.sayHi(); // Hi undefined
出典:this:https://poiemaweb.com/js-this
矢印関数:https://poiemaweb.com/es6-arrow-function#3-this
Reference
この問題について(JSのthis), 我々は、より多くの情報をここで見つけました
https://velog.io/@adguy/JS에서-this
テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol
function foo() {
console.log("foo's this: ", this); // window
function bar() {
console.log("bar's this: ", this); // window
}
bar();
}
foo();
var value = 1;
var obj = {
value: 100,
foo: function() {
console.log("foo's this: ", this); // obj
console.log("foo's this.value: ", this.value); // 100
function bar() {
console.log("bar's this: ", this); // window
console.log("bar's this.value: ", this.value); // 1
}
bar();
}
};
obj.foo();
前に説明しました.オブジェクトプロファイルとして登録されている関数(メソッド呼び出しフォーマット)はthisによって同じグローバルオブジェクトを指します.この場合、グローバルオブジェクトはウィンドウから他のオブジェクトに変更されます.
上のobj 1sayName()のこれはobj 1を表します.
上のobj 2sayName()のこれはobj 2を表します.
プロトタイプオブジェクトの内部で使用されるthisも、通常のメソッドのようにメソッドを呼び出すオブジェクトにバインドされます.
次はgetNameのthisがメソッドgetNameを呼び出すオブジェクトにバインドされています:me.
meはPerson()という関数に「Lee」パラメータを付けた例である.すなわち、関数Person(name){は新しいインスタンスであるため、関数Person(name){はjavaと同様であり、内部のthisは基本的にPersonを指し、インスタンスが作成されるとmeインスタンスオブジェクトを示す.
つまりPerson(‘Lee’)の実例が生まれた.nameは「Lee」の値をインスタンスのグローバル変数nameの値に伝播しますか?出力
me.getName()
なら5行目のPersonprototype.getName関数のthis.nameは先ほど伝播したname値を受け入れ,Leeを出力する.つまり、プロトタイプとして定義されたオブジェクトもメソッドであるため、プロトタイプを使用してバンドルされた親グローバルオブジェクトを指します.
例外:矢印関数定義メソッドを使用すると、矢印関数のthisはコンテキストwindowを指します.したがって、メソッドを定義する際に矢印関数を使用することは避けてください.
// Bad
const person = {
name: 'Lee',
sayHi: () => console.log(`Hi ${this.name}`)
};
person.sayHi(); // Hi undefined
出典:this:https://poiemaweb.com/js-this矢印関数:https://poiemaweb.com/es6-arrow-function#3-this
Reference
この問題について(JSのthis), 我々は、より多くの情報をここで見つけました https://velog.io/@adguy/JS에서-thisテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol