๐ก๋ฆฌ๋ง์ธ๋
- ์คํ ์ปจํ
์คํธ๋ ์คํํ ์ฝ๋์ ์ ๊ณตํ ํ๊ฒฝ ์ ๋ณด๋ค์ ๋ชจ์๋์ ๊ฐ์ฒด์ด๋ค.
- ๊ทธ ๊ฐ์ฒด ์์๋ 3๊ฐ์ง๊ฐ ์กด์ฌํ๋ค.
โ VariableEnvironment
โ LexicalEnvironment
โ ThisBindings
์ํฉ์ ๋ฐ๋ผ ๋ฌ๋ผ์ง๋ this
this๋ ์คํ ์ปจํ ์คํธ๊ฐ ์์ฑ๋ ๋ ๊ฒฐ์ ๋๋ค. ์ด ๋ง์ this๋ฅผ bindํ๋ค(=๋ฌถ๋๋ค) ๋ผ๊ณ ๋ ํ๋ค. ๋ค์ ๋งํ๋ฉด this๋ ํจ์๋ฅผ ํธ์ถํ ๋ ๊ฒฐ์ ๋๋ค.
1. ์ ์ญ ์์์ this
๋ฐํ์ ํ๊ฒฝ์ ๋ฐ๋ผ this๋ window(๋ธ๋ผ์ฐ์ ํ๊ฒฝ) ๋๋ global(node ํ๊ฒฝ)๋ฅผ ๊ฐ๋ฆฌํจ๋ค.
๋ฐํ์ ํ๊ฒฝ?
์ฌ๋ฌ๋ถ๋ค์ด javascript๋ก ๋ง๋ค์ด๋์ ํ๋ก๊ทธ๋จ์ด ๊ตฌ๋์ค์ธ ํ๊ฒฝ์ ๋งํ์ฃ .
์ฐ๋ฆฌ๋ node ํ์ผ์ด๋ฆ.js๋ก vscode ์์์ ๊ตฌ๋ํ๊ณ ์์ผ๋ node ํ๊ฒฝ์ด๋ผ๊ณ ํ ์ ์๊ตฌ์.
html ํ์ผ ์์ ์จ๊ฒจ๋์์ ํฌ๋กฌ๋ธ๋ผ์ฐ์ ๋ฑ์์ ์ฐ๋ค๊ณ ํ๋ค๋ฉด ๋ธ๋ผ์ฐ์ ํ๊ฒฝ์ด๋ผ๊ณ ํ ์ ์๊ฒ ๋ค์.
=> ์ ์ญ์์์ this๋ ๋ธ๋ผ์ฐ์ ์์๋ window, Nodeํ๊ฒฝ์์๋ global์ ๊ฐ๋ฆฌํจ๋ค.
// CASE1 : ํจ์
// ํธ์ถ ์ฃผ์ฒด๋ฅผ ๋ช
์ํ ์ ์๊ธฐ ๋๋ฌธ์ this๋ ์ ์ญ ๊ฐ์ฒด๋ฅผ ์๋ฏธํด์.
var func = function (x) {
console.log(this, x);
};
func(1); // Window { ... } 1
// CASE2 : ๋ฉ์๋
// ํธ์ถ ์ฃผ์ฒด๋ฅผ ๋ช
์ํ ์ ์๊ธฐ ๋๋ฌธ์ this๋ ํด๋น ๊ฐ์ฒด(obj)๋ฅผ ์๋ฏธํด์.
// obj๋ ๊ณง { method: f }๋ฅผ ์๋ฏธํ์ฃ ?
var obj = {
method: func,
};
obj.method(2); // { method: f } 2
2. ๋ฉ์๋๋ก์ ํธ์ถํ ๋์, ํจ์์์ ํธ์ถํ ๋์ ์ฐจ์ด => ํธ์ถํ๋ ์คํ ์ฃผ์ฒด์ ๋ฐ๋ผ this๊ฐ ๋ฌ๋ผ์ง๋ค.
1) ํจ์์์์ this => ์ ์ญ ๊ฐ์ฒด(window or global)
2) ๋ฉ์๋์์์ this => ํธ์ถ์ ์ฃผ์ฒด
=> ๋ฐ๋ผ์ ํจ์๋ฅผ ๋ ๋ฆฝ์ ์ผ๋ก ํธ์ถ ์์๋ this๊ฐ ํญ์ ์ ์ญ๊ฐ์ฒด๋ฅผ ๊ฐ๋ฆฌํจ๋ค.
=> ๋ฉ์๋ ๋ด๋ถ ํจ์์์๋ ์์ธ์๋ค. ๋ฉ์๋ ๋ด๋ถ์ ํจ์ ์์์ this๋ฅผ ํธ์ถํ ๊ฒฝ์ฐ, ๊ธฐ์กด ๋ฉ์๋ ํธ์ถ ์ฃผ์ฒด์ ๋ํ this์ ์ ๋ณด๋ฅผ ์๊ณ ์ ์ญ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ๋ค. => ํจ์์ด๊ธฐ ๋๋ฌธ
var obj1 = {
outer: function() {
console.log(this); // (1) obj1
var innerFunc = function() {
console.log(this); // (2) winodw
innerFunc();
var obj2 = {
innerMethod: innerFunc // (3) obj2
};
obj2.innerMethod();
}
};
obj1.outer();
๐ก์ฉ์ด ๊ธฐ์ต
AS - IS => ๊ธฐ์กด ๊ฒ ์๋ฏธ
TO - BE => ์ดํ ๊ฒ ์๋ฏธ
3. ํ์ดํ ํจ์์์์ this
ES6์์ ์ฒ์ ๋์ ๋ ํ์ดํ ํจ์๋, ์คํ ์ปจํ ์คํธ๋ฅผ ์์ฑํ ๋ this ๋ฐ์ธ๋ฉ ๊ณผ์ ์์ฒด๊ฐ ์๋ค(๋ฐ๋ผ์, this๋ ์ด์ ์ ๊ฐ์ด ์ ์ง๋๋ค. => ๋ฉ์๋ ๋ด๋ถ์ ํ์ดํ ํจ์ ์์์ this๋ฅผ ํธ์ถ ํ ๋, this ๋ฐ์ธ๋ฉ ์์ฒด๋ฅผ ํ์ง ์๊ธฐ ๋๋ฌธ์, this์ ์ฐธ์กฐ ๊ด๊ณ๋ฅผ ์์ง ์๊ณ ๊ธฐ์กด์ ๋ฉ์๋์์ ์ฐธ์กฐํ ํธ์ถ ๊ฐ์ฒด๋ฅผ ์ฌ์ ํ ์ฐธ์กฐํ๋ค.
var obj = {
outer: function() {
console.log(this); // (1) obj
var innerFunc = () => {
console.log(this); // (2) obj
};
innerFunc();
}
}
obj.outer();
=> ES6์์๋ ํจ์ ๋ด๋ถ์์ this๊ฐ ์ ์ญ๊ฐ์ฒด๋ฅผ ๋ฐ๋ผ๋ณด๋ ๋ฌธ์ ๋๋ฌธ์ ํ์ดํํจ์๋ฅผ ๋์ ํ๋ค.
๐ก๋ฉด์ ์์ ์ผ๋ฐ ํจ์์ ํ์ดํ ํจ์์ ๊ฐ์ฅ ํฐ ์ฐจ์ด์ ์ ๋ฌด์์ธ๊ฐ์?
๋ผ๊ณ ๋ฌผ์ผ๋ฉด > this binding ์ฌ๋ถ๊ฐ ๊ฐ์ฅ ์ ์ ํ ๋ต
4. ์ฝ๋ฐฑ ํจ์ ํธ์ถ ์ ๊ทธ ํจ์ ๋ด๋ถ์์์ this
=> ์ฝ๋ฐฑ ํจ์๋ ํจ์์ด๊ธฐ ๋๋ฌธ์ ๊ทธ ํจ์ ๋ด๋ถ์์ this ํธ์ถ ์ this๋ฅผ ์๊ณ ์ ์ญ ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ๋ค. (๋จ, ์ฝ๋ฐฑ์์ ํ์ดํ ํจ์ ์ง์ ์ this ๋ฐ์ธ๋ฉx ์ ์ญ๊ฐ์ฒด ์ฐธ์กฐx)
ํ์ง๋ง ๋ณ๋ ์์ธ๋ก this๋ฅผ ์ง์ ํ ๊ฒฝ์ฐ ๊ทธ ๋์์ ์ฐธ์กฐํ๋ค. ex) addEventListener
// ๋ณ๋ ์ง์ ์์ : ์ ์ญ๊ฐ์ฒด
setTimeout(function () { console.log(this) }, 300);
// ๋ณ๋ ์ง์ ์์ : ์ ์ญ๊ฐ์ฒด
[1, 2, 3, 4, 5].forEach(function(x) {
console.log(this, x);
});
// addListener ์์์์ this๋ ํญ์ ํธ์ถํ ์ฃผ์ฒด์ element๋ฅผ returnํ๋๋ก ์ค๊ณ๋์์
// ๋ฐ๋ผ์ this๋ button์ ์๋ฏธํจ
document.body.innerHTML += '<button id="a">ํด๋ฆญ</button>';
document.body.querySelector('#a').addEventListener('click', function(e) {
console.log(this, e);
});
addEventListner ๋ฉ์๋๋ ์ฝ๋ฐฑ ํจ์ ํธ์ถ ์, ์์ ์ this๋ฅผ ์์ํ๋ฏ๋ก, this๋ addEventListner์ ์๋ถ๋ถ(button ํ๊ทธ)์ด๋ค.
5. ์์ฑ์ ํจ์ ๋ด๋ถ์์์ this
์์ฑ์ : ๊ตฌ์ฒด์ ์ธ ์ธ์คํด์ค => class์ constructor๋ ์์ฑ์ ํจ์์์์ ์์ฑ์ ํจ์ this.~๊ฐ ๋ค์ด์๋..
=> ์์ฑ์ ํจ์์์์ tihs๋ ํญ์ ์ธ์คํด์ค๋ฅผ ์ง์ ํ๋ค.
var Cat = function (name, age) { //์์ฑ์
this.bark = '์ผ์น';
this.name = name;
this.age = age;
};
var choco = new Cat('์ด์ฝ', 7); //this : choco => ์ธ์คํด์ค
var nabi = new Cat('๋๋น', 5); //this : nabi
6. ๋ช ์์ this ๋ฐ์ธ๋ฉ
์๋์ผ๋ก ๋ถ์ฌ๋๋ ์ํฉ๋ณ this์ ๊ท์น์ ๊นจ๊ณ this์ ๋ณ๋์ ๊ฐ์ ์ ์ฅํ๋ ๋ฐฉ๋ฒ
1. call / apply / bind
var func = function (a, b, c) {
console.log(this, a, b, c);
};
// no binding
func(1, 2, 3); // Window{ ... } 1 2 3
// ๋ช
์์ binding
// func ์์ this์๋ {x: 1}์ด binding๋ผ์
func.call({ x: 1 }, 4, 5, 6}; // { x: 1 } 4 5 6
2. ์ ์ฌ๋ฐฐ์ด๊ฐ์ฒด => Array.from()
// ์ ์ฌ๋ฐฐ์ด
var obj = {
0: 'a',
1: 'b',
2: 'c',
length: 3
};
// ๊ฐ์ฒด -> ๋ฐฐ์ด
var arr = Array.from(obj);
// ์ฐ์ด๋ณด๋ฉด ๋ฐฐ์ด์ด ์ถ๋ ฅ๋ฉ๋๋ค.
console.log(arr);
3. bind( ) => ์ฆ์ ํธ์ถํ์ง๋ ์๊ณ ๋ฏธ๋ฆฌ ๋๊ฒจ๋ฐ์ this ๋ฐ ์ธ์๋ค์ ์ ์ฉ
var func = function (a, b, c, d) {
console.log(this, a, b, c, d);
};
func(1, 2, 3, 4); // window๊ฐ์ฒด
// ํจ์์ this ๋ฏธ๋ฆฌ ์ ์ฉ
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); // 4์ 5๋ฅผ ๋ฏธ๋ฆฌ ์ ์ฉ
bindFunc2(6, 7); // { x: 1 } 4 5 6 7
bindFunc2(8, 9); // { x: 1 } 4 5 8 9
var obj = {
outer: function() {
console.log(this);
var innerFunc = function () {
console.log(this);
}.bind(this); // innerFunc์ this๋ฅผ ๊ฒฐํฉํ ์๋ก์ด ํจ์๋ฅผ ํ ๋น
innerFunc();
}
};
obj.outer();
4. ํ์ดํ ํจ์๋ ์คํ ์ปจํ ์คํธ ์์ฑ ์, this๋ฅผ ๋ฐ์ธ๋ฉ ํ์ง ์์
var obj = {
outer: function () {
console.log(this);
var innerFunc = () => {
console.log(this);
};
innerFunc();
};
};
obj.outer();
* ์ ๋ด์ฉ์ ์คํ๋ฅดํ ์ฝ๋ฉํด๋ฝ JavaScript ๋ฌธ๋ฒ ์ข ํฉ๋ฐ ๊ฐ์ ๋ด์ฉ์ ๋๋ค.