๋์ ์
- this๋ ํจ์๋ฅผ ํธ์ถํ ๋ ๊ฒฐ์ ๋๋ค.
- ํจ์๋ฅผ ํจ์๋ก์ ํธ์ถํ ๊ฒฝ์ฐ์๋ this๊ฐ ์ง์ ๋์ง ์๋๋ค.
- this์๋ ํธ์ถํ ์ฃผ์ฒด์ ๋ํ ์ ๋ณด๊ฐ ๋ด๊ธด๋ค.
- ์คํ ์ปจํ ์คํธ๋ฅผ ํ์ฑํํ ๋น์์ this๊ฐ ์ง์ ๋์ง ์์ ๊ฒฝ์ฐ this๋ ์ ์ญ ๊ฐ์ฒด๋ฅผ ๋ฐ๋ผ๋ณธ๋ค.
function func1() {
console.log(this);
}
obj ={
func1:func1,
}
func1(); // Window
obj.func1() // obj
- ๋ฉ์๋๋ ๊ฐ์ฒด์ ๋ฉ์๋๋ก์ ํธ์ถํ ๊ฒฝ์ฐ์๋ง ๋ฉ์๋๋ก ๋์ํ๊ณ , ๊ทธ๋ ์ง ์์ผ๋ฉด ํจ์๋ก ๋์ํ๋ค.
- this ๋ฐ์ธ๋ฉ์ ๊ดํด์๋ ํจ์๋ฅผ ์คํํ๋ ๋น์์ ์ฃผ๋ณ ํ๊ฒฝ(๋ฉ์๋ ๋ด๋ถ์ธ์ง, ํจ์ ๋ด๋ถ์ธ์ง)๋ ์ค์ํ์ง ์๋ค.
- ์ค์ง ํด๋น ํจ์๋ฅผ ํธ์ถํ๋ ๋์, ์์ ์ ๋๋ ๋๊ดํธ ํ๊ธฐ๊ฐ ์๋์ง ์๋์ง๊ฐ ๊ด๊ฑด์ด๋ค.
const obj = {
method() {
console.log(this); // obj, obj.method()๋ก์จ ํธ์ถ๋จ(๋ฉ์๋)
function innerMethod() {
console.log(this); // Window, innerMethod()๋ก์จ ํธ์ถ๋จ(ํจ์)
}
innerMethod();
},
};
obj.method();
class Foo {
method() {
console.log(this);
[1,2].forEach(function(i) {
console.log(this); // forEach ๋ด๋ถ์์ callback()์ผ๋ก ๋ถ๋ฆฌ๊ธฐ์ "ํจ์๋ก์จ" ํธ์ถ
});
}
}
const f = new Foo()
f.method();
// Foo, window, window
ํ์ดํ ํจ์ vs ์ผ๋ฐ ํจ์
- ํ์ดํ ํจ์๋ ํธ์ถ ์ ์๋ก์ด ์คํ ์ปจํ ์คํธ๋ฅผ ๋ง๋ค๋, this ๋ฐ์ธ๋ฉ์ ํ์ง ์๋๋ค.
- ECMAScript ๋ช ์ธ์ ๋ฐ๋ฅด๋ฉด, ํ์ดํ ํจ์๋ Environment Record์์ this ๊ฐ์ ์ค์ ํ์ง ์๋๋ค๊ณ ๋ช ์๋์ด ์๋ค.
- ๊ทธ๋ ๊ธฐ ๋๋ฌธ์ this ๊ฐ์ ๋ถ๋ฌ์ค๊ธฐ ์ํด ์์ฐ์ค๋ฝ๊ฒ ์์ ์ค์ฝํ๋ก ์ฒด์ด๋ํด์ ๊ฐ์ ์ฐพ๋๋ค.
class Foo {
method() {
console.log(this);
[1,2].forEach((i) => {
console.log(this); // ()=>{}์์ this๊ฐ์ด ์์ผ๋ฏ๋ก ์ค์ฝํ ์ฒด์ด๋ํด์ ๊ฐ์ ์ฐพ์
});
}
}
const f = new Foo()
f.method();
// Foo, Foo, Foo
const obj1 = {
method() {
console.log(this);
},
};
const obj2 = {
method: () => {
console.log(this);
},
};
const func = obj1.method;
obj1.method(); // obj1
obj2.method(); // Window
func(); // Window
- ์ผ๋ฐ ํจ์๋ ํจ์๋ฅผ ํธ์ถํ ๋ ํจ์๊ฐ ์ด๋ป๊ฒ ํธ์ถ๋์๋์ง์ ๋ฐ๋ผ this์ ๋ฐ์ธ๋ฉํ ๊ฐ์ฒด๊ฐ ๋์ ์ผ๋ก ๊ฒฐ์ ๋๋ค.
- ํ์ดํ ํจ์๋ ํจ์ ๋ด๋ถ์ this๊ฐ ์์ ์์ด, ํธ์ถํ ๊ฐ์ฒด๋ฅผ this์ ๋ฐ์ธ๋ฉํ์ง ์๋๋ค.
- ํ์ดํ ํจ์๋ ํจ์๊ฐ ํธ์ถ๋๋ ์์ ์ ์ค์ฝํ์ฒด์ธ์ ๊ฐ์ฅ ๊ฐ๊น์ด this๊ฐ ์ ์ ์ผ๋ก ๊ฒฐ์ ๋๋ค.
const obj1 = {
method() {
console.log(this) // obj1
function innerMethod() {
console.log(this); // winodw
}
innerMethod();
},
};
const obj2 = {
method() {
console.log(this) // obj2
const innerMethod = () => {
console.log(this); // obj2
};
innerMethod();
},
};
const obj3 = {
method: () => {
console.log(this) // window
const innerMethod = () => {
console.log(this); // window
};
innerMethod();
},
};
obj1.method();
obj2.method();
obj3.method();
์ค๊ฐ์ ๋ฆฌ
1. ํจ์๋ฅผ ํจ์๋ก์จ ํธ์ถํ ๊ฒฝ์ฐ this๊ฐ ์ง์ ๋์ง ์๋๋ค.
2. ์ง์ ๋์ง ์๋ this๋ window๋ฅผ ๊ฐ๋ฆฌํจ๋ค.
3. But, ํจ์๋ฅผ ๋ฉ์๋๋ก์จ ํธ์ถํ ๊ฒฝ์ฐ this๋ ํธ์ถํ ์ฃผ์ฒด์ธ ๊ฐ์ฒด๋ฅผ ๊ฐ๋ฆฌํจ๋ค.
4. ํ์ดํ ํจ์๋ ๋ฉ์๋๋ก์จ ํธ์ถํ์ฌ๋, ํจ์ ๋ด๋ถ์ this๊ฐ ์๊ธฐ ๋๋ฌธ์ ํธ์ถ๋๋ ์์ ์ ์์ ์ค์ฝํ์ this๋ฅผ ๊ฐ๋ฆฌํจ๋ค. (๊ฐ์ฅ ๊ฐ๊น์ด this๋ฅผ ์ฒด์ด๋ํ๋ ๊ฒ)
const person = {
name: 'Lee',
sayHi() { // === sayHi: function() {
console.log(`Hi ${this.name}`);
}
};
person.sayHi(); // Hi Leeโ
const person = {
name: 'Lee',
sayHi: () => console.log(`Hi ${this.name}`)
};
person.sayHi(); // Hi undefined(window.name)
ํ์ดํ ํจ์๋ call, apply, bind ๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌ this๋ฅผ ๋ณ๊ฒฝํ ์ ์๋ค.
window.x = 1;
const normal = function () { return this.x; };
const arrow = () => this.x;
console.log(normal.call({ x: 10 })); // 10
console.log(arrow.call({ x: 10 })); // 1
normal์ ํจ์๋ก์จ ํธ์ถ๋์ง๋ง, callํจ์์ ์ํด ํจ์ ๋ด๋ถ์ this๊ฐ {x:10}์ผ๋ก ๋ฐ์ธ๋ฉ ๋๋ค.
arrow ํจ์๋ด๋ถ์ this๊ฐ ์์ ์๊ธฐ ๋๋ฌธ์ thisArg๋ฅผ {x:10}์ ์ฃผ์ด๋ ์ฐธ์กฐํ์ง ๋ชปํ๋ค.
(์ต์ข ๋ณด์ค) ๋ฉ์๋๋ก์จ ํธ์ถ๋์์ ๋ this๊ฐ์ด ๋ณํ๋ ๊ฒฝ์ฐ
function test(){
return {
rs : 25,
bar : function(){
console.log(this.rs);
}
}
}
test.call({rs:100}) // {rs:25, bar:function}
test.call({rs:100}).bar(); // 25
function test(){
return {
rs : 25,
bar : () => {
console.log(this.rs);
}
}
}
test.call({rs:100}) // {rs:25, bar:function}
test.call({rs:100}).bar(); // 100
์์ ์์๊ฐ ํ๊ฐ๋ ธ๋ ์ด์
- test.call({rs:100}): ์ด ์ฝ๋๋ thisArg๊ฐ์ {rs:100}์ผ๋ก ๋ฐ๊พธ๋ ๊ฒ์ด์ง, ๋ฆฌํด ๊ฐ ์์ฒด๋ฅผ ๋ฐ๊พธ๋ ๊ฒ์ด ์๋๋ค.
- test.call({rs:100})๋ ํจ์๋ฅผ ์คํํ ์ฝ๋๋ค. ์ฆ, ์คํ ์ปจํ ์ค๊ฐ ์์ฑ๋์ด ์ฝ์คํ์ ์์ฌ์๋ค๋ ๋ป์ด๋ค.
- ๋ฐ๋ผ์ test ์คํ ์ปจํ ์คํธ์ this๋ {rs:100}์ ๊ฐ๋๋ค
- ํ์ดํ ํจ์๋ ๋ฉ์๋๋ก์จ ํธ์ถ๋์ด๋, ๊ฐ์ฒด๋ฅผ this๋ก ๋ฐ์ธ๋ฉ ํ์ง ์๋๋ค. ๊ทธ๋ ๊ธฐ ๋๋ฌธ์ ํ์ดํ ํจ์๋ test์ ๋ฆฌํด ๊ฐ, {rs:25, bar:f}์ this๋ก ๋ณด์ง ๋ชปํ๊ณ , bar๊ฐ ์คํ๋๋ ์์ ์ธ,ํ์ดํ ํจ์์ ์ฝ์คํ ์์ ์๋ ์คํ ์ปจํ ์คํธ์ this๊ฐ, {rs:100}์ ์ฒด์ด๋ํ๋ค.
- ์ผ๋ฐ ํจ์๋ ๋ฉ์๋๋ก์จ ํธ์ถ๋๋ฉด this๊ฐ์ ํธ์ถ ๋์์ ๊ฐ๋ฆฌํค๊ธฐ ๋๋ฌธ์ this๋ test์ ๋ฆฌํด ๊ฐ, {rs:25, bar:f}์ ๋ฐ๋ผ๋ณธ๋ค.
์คํด๊ธ์ง!
์์ ์์๋ฅผ ์ฝ๋ค๋ณด๋ฉด ์ด๋ฐ ์๊ฐ์ ํ ์ ์๋ค. "ํ์ดํ ํจ์์ this๋ call๊ณผ ๊ฐ์ ๋ฐ์ธ๋ฉ ๋ฉ์๋๋ก ๊ฐ์ด ๋ณํ ์ ์๊ตฌ๋!" BullShit! ์ ๋ ์๋๋ค. ํ์ดํ ํจ์๋ ํจ์ ๋ด๋ถ์ this ๋ฐ์ธ๋ฉ ๊ณผ์ ์ด ์๋ต๋์ด ์์ด, ํธ์ถ ๋์์ this ๊ฐ์ผ๋ก ๋ฐ์ธ๋ฉ ํ์ง ๋ชปํ๋ค. ๋ฐ๋ผ์ ๊ทธ์ ์์ ์ค์ฝํ์ this๋ฅผ ๋ฐ๋ผ๋ณผ ๋ฟ์ด์ง, ํ์ดํ ํจ์์ ๋ฐ์ธ๋ฉ ๋ฉ์๋๋ ์ ํ ์๋ฏธ ์๋ค. ๋จ์ง ์์ ์์๋ ํ์ดํ ํจ์๊ฐ this๊ฐ์ ์ฐพ์ผ๋ฌ ์์ ์ค์ฝํ์ this๋ฅผ ์ฐธ์กฐํ๋ ค๊ณ ํ ๋, ๋ฐ์ธ๋ฉ ๋ฉ์๋์ this๋ฅผ ๋ง๋ ๊ทธ ๊ฐ์ ์ฐธ์กฐํ์ ๋ฟ์ด๋ค.
์ด์ ๋ฌ๋ฆฌ, ์ผ๋ฐ ํจ์๋ ํจ์ ๋ด๋ถ์ this ๊ฐ์ ๋ฐ์ธ๋ฉํ๋ ๊ณผ์ ์ด ์๊ณ , test()์ ๋ฉ์๋๋ก์จ ํธ์ถ๋๊ธฐ ๋๋ฌธ์ ํธ์ถ๋์์ด์, ๋ฆฌํด ๊ฐ์ธ ๊ฐ์ฒด๋ฅผ this๋ก ๋ฐ๋ผ๋ณผ ์ ์๊ฒ ๋๋ค.
function test(){
return {
rs : 25,
bar : function(){
console.log(this.rs);
}
}
}
test().bar()
function test(){
return {
rs : 25,
bar : () => {
console.log(this.rs);
}
}
}
test().bar()
๊ณต๋ถํ๋ ์๋ฃ์ ํ ๋ฌ์ ๋ณด๊ธฐ
1. ES5 function ์์ this๋ ์์ ์ ๊ฐ์ฅ ๋ง์ง๋ง์ผ๋ก ํ๊ณ ์๋ scope๋ก ํญ์ ๋ณํ๋ค.
=> this๊ฐ์ด ๋ณํ๋ ๊ฒ ์๋๋ค. function๋ฅผ ํธ์ถํ ๋ ์์ฑ๋๋ ์คํ ์ปจํ ์คํธ์ this๊ฐ์ ์ฐธ์กฐํ๋ ๊ฒ์ด๋ค.
2. arrow Function์ ์ฒ์ ๋ฐ์ธ๋ฉ ๋ ์ค์ฝํ ์์์ ๊ฐ๋ฆฌํค๋ this๊ฐ ์ ๋ ๋ณํ์ง ์๋๋ค.
=> ํ์ดํ ํจ์๋ ํธ์ถ๋๋ ์์ ์ ์คํ ์ปจํ ์คํธ์ this๋ฅผ ์ฐธ์กฐํ๋ค.
3. ํ์ดํ ํจ์์ this๋ ํธ์ถ๋ ํจ์๋ฅผ ๋๋ฌ์ผ ์คํ ์ปจํ ์คํธ๋ฅผ ๊ฐ๋ฆฌํจ๋ค.
=> ํ์ดํ ํจ์๋ ์คํ ์ปจํ ์คํธ ์์ฑ ์ this๋ฅผ ๋ฐ์ธ๋ฉํ๋ ๊ณผ์ ์ด ์ ์ธ๋๋ฏ๋ก, ์ค์ฝํ ์ฒด์ด๋์ ํตํ์ฌ ์์ ์ปจํ ์คํธ์ this๋ฅผ ๊ฐ๋ฆฌํจ๋ค.
4. ์ผ๋ฐ ํจ์์ this๋ ์๋กญ๊ฒ ์์ฑ๋ ์คํ ์ปจํ ์คํธ๋ฅผ ๊ฐ๋ฆฌํจ๋ค.
=>์ผ๋ฐ ํจ์์ this๋ ํจ์๋ก ํธ์ถ๋๋ฉด ์ค์ฝํ ์ฒด์ด๋์ ํตํ์ฌ ๋ฐ์ธ๋ฉ๋๊ณ , ๋ฉ์๋๋ก ํธ์ถ๋๋ฉด ๊ทธ ๊ฐ์ฒด๋ฅผ ๋ฐ์ธ๋ฉํ๋ค.
"use strict"
- Without "use strict": this in a standalone function call refers to the global object. (Window, global)
- With "use strict": this in a standalone function call is undefined.