์ํฉ์ ๋ฐ๋ผ์ ๋ฌ๋ผ์ง๋ this๋ฅผ ์ ๋ฆฌํด๋ณด๋ ค๊ณ ํ๋ค.
0 JavaScripot์์ this
1 ์ํฉ์ ๋ฐ๋ผ ๋ฌ๋ผ์ง๋ this
1-1 ์ ์ญ ๊ณต๊ฐ์์์ this
1-2 ๋ฉ์๋๋ก์ ํธ์ถํ ๋ ๊ทธ ๋ฉ์๋ ๋ด๋ถ์์์ this
ํจ์ vs ๋ฉ์๋
๋ฉ์๋ ๋ด๋ถ์์์ this
1-3 ํจ์๋ก์ ํธ์ถํ ๋ ๊ทธ ํจ์ ๋ด๋ถ์์์ this
ํจ์ ๋ด๋ถ์์์ this
๋ฉ์๋์ ๋ด๋ถํจ์์์์ this
๋ฉ์๋์ ๋ด๋ถ ํจ์์์์ this๋ฅผ ์ฐํํ๋ ๋ฐฉ๋ฒ
this๋ฅผ ๋ฐ์ธ๋ฉํ์ง ์๋ ํจ์
1-4 ์ฝ๋ฐฑ ํจ์ ํธ์ถ ์ ๊ทธ ํจ์ ๋ด๋ถ์์์ this
1-5 ์์ฑ์ ํจ์ ๋ด๋ถ์์์ this
2 ๋ช
์์ ์ผ๋ก this๋ฅผ ๋ฐ์ธ๋ฉํ๋ ๋ฐฉ๋ฒ
2-1 call ๋ฉ์๋
2-2 apply ๋ฉ์๋
2-3 call/apply ๋ฉ์๋์ ํ์ฉ
์ ์ฌ๋ฐฐ์ด๊ฐ์ฒด์ ๋ฐฐ์ด ๋ฉ์๋๋ฅผ ์ ์ฉ
์์ฑ์ ๋ด๋ถ์์ ๋ค๋ฅธ ์์ฑ์ ํธ์ถ
์ฌ๋ฌ ์ธ์๋ฅผ ๋ฌถ์ด ํ๋์ ๋ฐฐ์ด๋ก ์ ๋ฌํ๊ณ ์ถ์ ๋ apply ํ์ฉ
2-4 bind ๋ฉ์๋
name ํ๋กํผํฐ
์์ ์ปจํ
์คํธ์ this๋ฅผ ๋ด๋ถํจ์๋ ์ฝ๋ฐฑํจ์์ ์ ๋ฌํ๊ธฐ
2-5 arrow function์ ์์ธ์ฌํญ
2-6 ๋ณ๋์ ์ธ์๋ก this๋ฅผ ๋ฐ๋ ๊ฒฝ์ฐ(์ฝ๋ฐฑ ํจ์ ๋ด์์์ this)JavaScripot์์ this
-
๋ค๋ฅธ ๊ฐ์ ์งํฅ ์ธ์ด์ this์ ์ฐจ์ด์
-
๋ค๋ฅธ ๋๋ถ๋ถ์ ๊ฐ์ฒด์งํฅ ์ธ์ด์ this: ํด๋์ค๋ก ์์ฑํ ์ธ์คํด์ค ๊ฐ์ฒด
- ํด๋์ค์์๋ง ์ฌ์ฉํ ์ ์๊ธฐ ๋๋ฌธ์ ํท๊ฐ๋ฆฌ์ง ์๊ฑฐ๋ ๋ง์ง ์์
-
์๋ฐ์คํฌ๋ฆฝํธ this: ์ด๋์์๋ ์ธ ์ ์์
- ์ํฉ์ ๋ฐ๋ผ this๊ฐ ๋ฐ๋ผ๋ณด๋ ๋์์ด ๋ฌ๋ผ์ง
- ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ค๋ฉด ์์ธ์ ์์์ผ ํ๋๋ฐ, ์ ํํ ์๋๋ฐฉ์์ ์ดํดํ์ง ๋ชปํ๋ฉด ์์ธ์ ํด๊ฒฐํ๊ธฐ ์ด๋ ค์
-
- this ํ์ธ์ผ๋ก 'ํจ์, ๊ฐ์ฒด(๋ฉ์๋)'์ ๊ตฌ๋ถํ ์ ์๋ ๊ฑฐ์ ์ ์ผํ ๋ฐฉ๋ฒ
1 ์ํฉ์ ๋ฐ๋ผ ๋ฌ๋ผ์ง๋ this
this๋ ๊ธฐ๋ณธ์ ์ผ๋ก ์คํ ์ปจํ ์คํธ๊ฐ ์์ฑ๋ ๋ ํจ๊ป ๊ฒฐ์ (์คํ์ปจํ ์คํธ ์ค๋ช ํ ๋ ์ค๋ช ๋จ)
์๋ ์ํฉ๋ณ๋ก this๊ฐ 5๊ฐ์ง ๋ค๋ฅธ ๊ฐ์ ๋ณด์ฌ์ฃผ๋ ๋ด์ฉ์ ์ค๋ช
1-1 ์ ์ญ ๊ณต๊ฐ์์์ this
์ ์ญ ๊ณต๊ฐ์์ this๋ ์ ์ญ๊ฐ์ฒด๋ฅผ ๊ฐ๋ฆฌํจ๋ค.
-
์ ์ญ ๋ณ์์ ์ ์ญ๊ฐ์ฒด
var a = 1 console.log(a) //1 console.log(window.a) //1 console.log(this.a) //1 -
์ ๊ฒฐ๊ณผ ๊ฐ์ด ๊ฐ์์ด์ ๋?
- ์ ์ญ๋ณ์ ์ ์ธ์ javascrip engine์ด ์ ์ญ๊ฐ์ฒด์ ํ๋กํผํฐ๋ก ํ ๋น
-
javascript ๋ชจ๋ ๋ณ์๋ ํน์ ๊ฐ์ฒด์ ํ๋กํผํฐ๋ก ๋ฑ๋ก๋๊ณ ๋์
- ํน์ ๊ฐ์ฒด: ์คํ์ปจํ ์คํธ์ LexicalEnvironment
- ์ ์ญ์ปจํ ์คํธ์ ๊ฒฝ์ฐ LexicalEnvironment๋ ์ ์ญ๊ฐ์ฒด๋ฅผ ๊ทธ๋๋ก ์ฐธ์กฐ(์คํ์ปจํ ์คํธ ๋์ํ ๊ทธ๋ฆผ ์ฐธ๊ณ
-
์ ์ญ ๋ณ์๋ฅผ ์ ๊ทผํ๋ ๊ณผ์ ์? -> scope chain
- a์ ์ ๊ทผํ๊ณ ์ ํ๋ฉด ์ค์ฝํ ์ฒด์ธ์์ a๋ฅผ ๊ฒ์ํ๋ค ๊ฐ์ฅ ๋ง์ง๋ง์ ๋๋ฌํ๋ '์ ์ญ ์ค์ฝํ'์ LexcialEnvironment(์ ์ญ๊ฐ์ฒด)์์ ํด๋น ํ๋กํผํฐ๋ฅผ a๋ฅผ ๋ฐ๊ฒฌํด์ ๊ทธ ๊ฐ์ ๋ฐํํ๊ธฐ ๋๋ฌธ
-
์ ์ญ๋ณ์์ ์ ์ญ๊ฐ์ฒด์ ์ฐจ์ด์
- ์ ์ญ๊ฐ์ฒด์ ํ๋กํผํฐ๋ก ํ ๋นํ ๊ฒฝ์ฐ์์๋ ์ญ์ o
- ์ ์ญ๋ณ์๋ก ์ ์ธํ ๊ฒฝ์ฐ์๋ ์ญ์ x
var b = 2; delete b; //false console.log(b, window.b, this.b) //2 2 2 window.c = 3; delete window.c; //true console.log(c, window.c this.c); // Uncaught ReferenceError: c is not defined
1-2 ๋ฉ์๋๋ก์ ํธ์ถํ ๋ ๊ทธ ๋ฉ์๋ ๋ด๋ถ์์์ this
ํจ์ vs ๋ฉ์๋
-
ํจ์๋ฅผ ์คํํ๋ ๋ฐฉ๋ฒ 2๊ฐ์ง: ํจ์ํธ์ถ, ๋ฉ์๋
- ํจ์: ๊ทธ ์์ฒด๋ก ๋ ๋ฆฝ์ ์ธ ๊ธฐ๋ฅ์ ์ํ
- ๋ฉ์๋: ์์ ์ ํธ์ถํ ๋์ ๊ฐ์ฒด์ ๊ดํ ๋์์ ์ํ
-
ํจ์, ๋ฉ์๋๋ก ํธ์ถ์ this์ ์ฐจ์ด
- ํจ์ ํธ์ถ์ this: ์ ์ญ๊ฐ์ฒด (์๋ ์์ ์ฝ๋ POINT ์ฃผ์ ์ฐธ๊ณ )
- ๋ฉ์๋๋ก ํธ์ถ์ this: ํธ์ถํ ๋ฉ์๋
ํจ์๋ก์ ํธ์ถ, ๋ฉ์๋๋ก์ ํธ์ถ ๋น๊ต
var func = function(x){
console.log(this, x);
}
func(1); // Window{...} 1
var obj = {
method: func
}
obj.method(2) // {method: f} 2-
ํจ์๋ก์ ํธ์ถ์ ์ผ๋ฐํจ์, arrow function ์ฌ๋ถ์ ๋ฐ๋ฅธ ์ฐจ์ด
var obj = { bar: function() { // ํจ์๋ก์ ํธ์ถ์ ์ผ๋ฐํจ์ console.log(this) // {bar:f} return function() { return this; // this = window }; }, } obj.bar()() === window //true //POINTvar obj = { bar: function() { // ํจ์๋ก์ ํธ์ถ์ arrow function return () => this; //POINT: this = bar (์ฃผ์: use arrow funciton) } }; obj.bar()() === obj //true
1-3 ํจ์๋ก์ ํธ์ถํ ๋ ๊ทธ ํจ์ ๋ด๋ถ์์์ this
ํจ์ ๋ด๋ถ์์์ this
- this์๋ ํธ์ถํ ์ฃผ์ฒด ์ ๋ณด๊ฐ ๋ด๊ธฐ๋๋ฐ ์ด๋ค ํจ์๋ฅผ ํจ์๋ก์ ํธ์ถ์ this ์ง์ ์๋จ
- ํจ์๋ก์ ํธ์ถํ๋ ๊ฒ์ ํธ์ถ ์ฃผ์ฒด(๊ฐ์ฒด์งํฅ ์ธ์ด์์์ ๊ฐ์ฒด)๋ฅผ ๋ช ์ํ์ง ์๊ณ ๊ฐ๋ฐ์๊ฐ ์ฝ๋์ ์ง์ ๊ด์ฌํด์ ์คํํ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ ํธ์ถ ์ฃผ์ฒด์ ์ ๋ณด๋ฅผ ์ ์ ์๋ค.
- ์คํ ์ปจํ ์คํธ๊ฐ ์ง์ ๋์ง ์์ ๊ฒฝ์ฐ this๋ ์ ์ญ ๊ฐ์ฒด๋ฅผ ๋ฐ๋ผ๋ณธ๋ค -> ๋ฐ๋ผ์ ํจ์์์ this๋ ์ ์ญ๊ฐ์ฒด๋ฅผ ๊ฐ๋ฆฌํจ๋ค.
๋ฉ์๋์ ๋ด๋ถํจ์์์์ this
-
์คํ์์1,2,3์ return value
- ์คํ์์1: {outer: f, outer2: f} === obj1
- ์คํ์์2: window{...}
- ์คํ์์3: {obj2Property: "obj2Property", innerMethod: ฦ}
- ํฌ์ธํธ๋ ์คํ์์2, 3์ ๊ฐ์ function์ ํธ์ถํ์ง๋ง ํจ์๋ก์ ํธ์ถ(์คํ์์2), ํจ์๋ก์ ํธ์ถ(์คํ์์3)์ ๋ฐ๋ผ this๊ฐ์ด ๋ฌ๋ผ์ง๋ค.
-
POINT
- innerFunc์ console.log๋ B, C์ ์ํด์ ํธ์ถ์ด ๋๋๋ฐ
- B์ฒ๋ผ innerFunc์ด ํจ์๋ก ํธ์ถ๋ ๋๋ this๋ ์ ์ญ ๋ณ์๋ฅผ ๊ฐ๋ฅดํจ๋ค.
- C์ฒ๋ผ innerfunc์ด ๋ฉ์๋๋ก ํธ์ถ๋ ๋๋ this๋ ํธ์ถํ ๋์์ ๊ฐ๋ฅดํจ๋ค.
var obj1 = { outer: function() { console.log(this) //์คํ์์1 by A var innerFunc = function() { console.log(this) //์คํ์์2 by B / ์คํ์์3 by C } innerFunc() // B var obj2 = { innerMethod: innerFunc, obj2Property: "obj2Property", } obj2.innerMethod() // C }, outer2: function() {}, } obj1.outer() // A
๋ฉ์๋์ ๋ด๋ถ ํจ์์์์ this๋ฅผ ์ฐํํ๋ ๋ฐฉ๋ฒ
- POINT ์ฐธ๊ณ
var obj1 = {
outer: function() {
console.log(this) // {outer: f}
var innerFunc1 = function() {
console.log(this) // window {...}
}
innerFunc1();
var me = this; // <= POINT
var innerFunc2 = function() {
console.log(me); // <= POINT: {outer: f}
}
innerFunc2()
},
}
obj1.outer() this๋ฅผ ๋ฐ์ธ๋ฉํ์ง ์๋ ํจ์
์๋ ์์ ์ฃผ์ ์ฐธ๊ณ
-
log ๊ฒฐ๊ณผ๊ฐ
- [1]: {outer: f}
- [2]: window {...}
- [3]: {outer: f}
- [4]: window {...}
- [5]: {outer: f}
var obj1 = { outer: function() { console.log(this) // [1] var innerFunc = function() { console.log(this) // [2] } innerFunc() var me = this var innerFunc2 = function() { console.log(me) // [3] POINT ๋ฉ์๋์ ๋ด๋ถ ํจ์์์์ this๋ฅผ ์ฐํํ๋ ๋ฐฉ๋ฒ console.log(this) // [4] } innerFunc2() var innerFunc3 = () => { console.log(this) // [5] POINT: this๋ฅผ ๋ฐ์ธ๋ฉํ์ง ์๋ ํจ์(arrow function) } innerFunc3() }, } obj1.outer()
1-4 ์ฝ๋ฐฑ ํจ์ ํธ์ถ ์ ๊ทธ ํจ์ ๋ด๋ถ์์์ this
callback function์ ์ ์ด๊ถ์ ๊ฐ์ง๋ ํจ์(๋ฉ์๋)๊ฐ ์ฝ๋ฐฑ ํจ์์์์ this๋ฅผ ๋ฌด์์ผ๋ก ํ ์ง๋ฅผ ๊ฒฐ์
ํน๋ณํ ์ ์ํ์ง ์์ ๊ฒฝ์ฐ์๋ ๊ธฐ๋ณธ์ ์ผ๋ก ํจ์์ ๋ง์ฐฌ๊ฐ์ง๋ก ์ ์ญ๊ฐ์ฒด๋ฅผ ๋ฐ๋ผ๋ณธ๋ค.
์ฝ๋ฐฑ ํจ์์ bind๋ฅผ ์ฌ์ฉํ์ฌ 2-4 bind
setTimeout(function() {
console.log(this) //window ๊ฐ์ฒด
}, 3000)
;
[1, 2, 3].forEach(function(v) {
console.log(this, v) //window ๊ฐ์ฒด
})
//event Callback function ์ฐธ๊ณ
document.body.innerHTML += `<button id="a"> ํด๋ฆญ </button>`
document.body.querySelector("#a").addEventListener("click", function(e) {
console.log(this, e)
})- "button click event Callback function this"๊ณผ "id='a' dom" ๊ฐ์ฒด ๋น๊ต => ๊ฐ๋ค.
-
addEventListner function ๋ด๋ถ ๊ตฌํ ์ถ์ธก
-
addEventListner function this๊ฐ 'document.body.querySelector('#a')' ์ด๊ธฐ ๋๋ฌธ์
์ด ๊ฐ์ callback function์ call๋ฉ์๋๋ฅผ ์ด์ฉํด ๋ช ์์ ์ผ๋ก this๋ฐ์ธ๋ฉ ํ ์ ์๊ฒ ๋ค.addEventListener: function(a, callbackFunc){ ... callbackFunc.call(this, event); ... }
-
1-5 ์์ฑ์ ํจ์ ๋ด๋ถ์์์ this
์์ฑ์ ํจ์์์ this๋ ์์ฑ๋ ์ธ์คํด์ค๋ฅผ ์ฐธ์กฐ
var Dog = function(name, age) {
this.bark = "RRRR"
this.name = name
this.age = age
}
var planets = new Dog("ํ์ฑ", 2)
var girl = new Dog("์๋
", 3)
var universe = new Dog("์ฐ์ฃผ", 1)
console.log(planets, girl, universe)
/*
planets: Dog {bark: "RRRR", name: "ํ์ฑ", age: 2}
girl: Dog {bark: "RRRR", name: "์๋
", age: 3}
universe: Dog {bark: "RRRR", name: "์ฐ์ฃผ", age: 1}
*/
console.log({ bark: planets.bark, name: planets.name, age: planets.age })
/*
{bark: "RRRR", name: "ํ์ฑ", age: 2}
*/- ์ ๋ console.log๋ฅผ ํ์ธํ์๋ Dog์์ํด์ ์์ฑ๋ instance๊ฐ this๊ฐ ๋๊ฒ์ํ์ธ ํ ์ ์๋ค.
2 ๋ช ์์ ์ผ๋ก this๋ฅผ ๋ฐ์ธ๋ฉํ๋ ๋ฐฉ๋ฒ
2 ์ด ๋ชฉ์ฐจ๋ call(), apply(), bind()์ ๋ํด์ ์์ธํ๊ฒ ๋ค๋ฃจ๋๋ก ์ํด์ ๋ค๋ฅธ ํฌ์คํธ์์ ์ค๋ช ํ๋๋กํ๋ค. call(), apply(), bind()
2-1 call ๋ฉ์๋
2-2 apply ๋ฉ์๋
2-3 call/apply ๋ฉ์๋์ ํ์ฉ
์ ์ฌ๋ฐฐ์ด๊ฐ์ฒด์ ๋ฐฐ์ด ๋ฉ์๋๋ฅผ ์ ์ฉ
์์ฑ์ ๋ด๋ถ์์ ๋ค๋ฅธ ์์ฑ์ ํธ์ถ
์ฌ๋ฌ ์ธ์๋ฅผ ๋ฌถ์ด ํ๋์ ๋ฐฐ์ด๋ก ์ ๋ฌํ๊ณ ์ถ์ ๋ apply ํ์ฉ
2-4 bind ๋ฉ์๋
name ํ๋กํผํฐ
์์ ์ปจํ ์คํธ์ this๋ฅผ ๋ด๋ถํจ์๋ ์ฝ๋ฐฑํจ์์ ์ ๋ฌํ๊ธฐ
var obj = {
outer: function() {
console.log(this) //{outer: ฦ, outer2: ฦ}
var innerFunc = function() {
console.log(this) //{outer: ฦ, outer2: ฦ}
}
innerFunc.call(this) //POINT
},
outer2: function() {
console.log(this) //{outer: ฦ, outer2: ฦ}
var innerFunc = function() {
console.log(this) //{outer: ฦ, outer2: ฦ}
}.bind(this) //POINT
innerFunc()
},
outer3: function() {
console.log(this) //{outer: ฦ, outer2: ฦ}
var innerFunc = function() {
console.log(this) // window{...}
} //POINT
innerFunc()
},
}
obj.outer()
obj.outer2()
obj.outer3()2-5 arrow function์ ์์ธ์ฌํญ
- "this๋ฅผ ๋ฐ์ธ๋ฉํ์ง ์๋ ํจ์" ๋ชฉ์ฐจ ์ฐธ๊ณ
2-6 ๋ณ๋์ ์ธ์๋ก this๋ฅผ ๋ฐ๋ ๊ฒฝ์ฐ(์ฝ๋ฐฑ ํจ์ ๋ด์์์ this)
var report = {
sum: 0,
count: 0,
add: function() {
var args = Array.prototype.slice.call(arguments)
args.forEach(function(arg, idx) {
debugger //idx๊ฐ 0์ผ๋ this -> {sum: 0, count: 0, add: ฦ, average: ฦ} :report ๊ฐ์ฒด
this.sum += arg
++this.count
}, this) //POINT
},
average: function() {
return this.sum / this.count
},
}
report.add(10, 20, 30)
console.log({ sum: report.sum, count: report.count, average: report.average() })
//{sum: 60, count: 3, average: 20}-
๋ง์ฝ ์ ์ฝ๋์์ POINT ๋ถ๋ถ forEach function์ ๋๋ฒ์งธ parameter "thisArg"๊ฐ ์์๋ค๋ฉด this.sum += entry;์์ this๋ window๊ฐ์ฒด๋ฅผ ๊ฐ๋ฅดํค๊ธฐ ๋๋ฌธ์ console.log ๊ฒฐ๊ณผ๋ ์๋์ ๊ฐ๋ค.
{sum: 0, count: 0, average: NaN}
- ์ฝ๋ฐฑํจ์์ ํจ๊ป thisArg๋ฅผ ์ธ์๋ก ๋ฐ๋ ๋ฉ์๋
Array.prototype.forEach(callback[, thisArg]);
Array.prototype.map(callback[, thisArg]);
Array.prototype.filter(callback[, thisArg]);
Array.prototype.some(callback[, thisArg]);
Array.prototype.every(callback[, thisArg]);
Array.prototype.find(callback[, thisArg]);
Array.prototype.findIndex(callback[, thisArg]);
Array.prototype.flatMap(callback[, thisArg]);
Array.prototype.from(callback[, thisArg]);
Set.prototype.forEach(callback[, thisArg]);
Map.prototype.forEach(callback[, thisArg]);์ฐธ๊ณ
- ์ฝ์ด ์๋ฐ์คํฌ๋ฆฝํธ - ์ํค๋ถ์ค
- ์ธ์ฌ์ด๋ ์๋ฐ์คํฌ๋ฆฝํธ
- ์๋ฐ์คํฌ๋ฆฝํธ ์๋ฒฝ ๊ฐ์ด๋