2021. 9. 26. 01:27ใ๐ Book/Core Javascript
1. ์คํ ์ปจํ ์คํธ (Execution context)
1 - 1. ์คํ ์ปจํ ์คํธ
์คํ ์ปจํ ์คํธ : ์ฝ๋๋ฅผ ์คํํ ๋ ์ ๊ณต๋๋ ํ๊ฒฝ ์ ๋ณด๋ฅผ ๋ชจ์ ๋ ๊ฐ์ฒด.
ํ๋์ ์คํ ์ปจํ ์คํธ๋ฅผ ์์ฑํ๋ ๋ฐฉ๋ฒ์ ์ฃผ๋ก ํจ์๋ฅผ ํธ์ถํ๋ ๊ฒ์ ๋๋ค.
(์ด์ธ์๋ ์ ์ญ๊ณต๊ฐ์ด๋ eval() ํจ์ ๋ฑ์ด ์์ง๋ง ์ง๊ธ์ ํจ์คํ๊ฒ ์ต๋๋ค.)
์คํ ์ปจํ ์คํธ๋ฅผ ์ง์ญํ๋ฉด ์คํ ๋ฌธ๋งฅ์ธ๋ฐ ์ฝ๋๋ฅผ ์คํํ๋ ๋ฌธ๋งฅ, ์ฆ ์ฝ๋๋ฅผ ์คํํ ๋ ํ์ํ ํ๊ฒฝ ์ ๋ณด๋ฅผ ๋ปํฉ๋๋ค.
๊ทธ๋ ๋ค๋ฉด ์ฝ๋๋ฅผ ์คํํ ๋ ํ์ํ ํ๊ฒฝ ์ ๋ณด๋ ๋ฌด์์ด๋ฉฐ, ์ด๋ป๊ฒ ์์ฑ๋๋ ๊ฒ์ผ๊น์?
๋ฐ๋ก ์๋ฐ์คํฌ๋ฆฝํธ ์์ง์ด ํธ์ถ๋๋ ํจ์์ ๊ด๋ จ๋ ์ ๋ณด(=ํ๊ฒฝ์ ๋ณด)๋ฅผ ์์งํ์ฌ ์คํ ์ปจํ ์คํธ ๊ฐ์ฒด์ ์ ๋ฌ/์ ์ฅํ ๋ ์์ฑ๋ฉ๋๋ค.
์ด ๊ฐ์ฒด(์คํ ์ปจํ ์คํธ) ๋ ์๋ฐ์คํฌ๋ฆฝํธ ์์ง์ด ํ์ฉํ ๋ชฉ์ ์ผ๋ก ์์ฑ๋๊ธฐ ๋๋ฌธ์ ๊ฐ๋ฐ์๊ฐ ์ง์ ํ์ธํ ์ ์์ต๋๋ค.
ํ๊ฒฝ์ ๋ณด๋ ์ฝ๋๋ฅผ ์คํํ ๋ ํ์ํ ์ ๋ณด๊ฐ ๋ด๊ธด ๊ฐ์ฒด๋ผ ํ์๊ณ , ์๋์ ๊ฐ์ ์ ๋ณด๋ฅผ ํฌํจํฉ๋๋ค.
- Variable Environment : ์ปจํ ์คํธ ๋ด ์๋ณ์์ ์ ๋ณด + ์ธ๋ถ ํ๊ฒฝ ์ ๋ณด, ์ ์ธ ์์ ์ Lexical Environment ์ ๊ฐ (๋ณ๊ฒฝ์ฌํญ ์ถ์ x)
- Lexical Environment : ์ด๊ธฐํ ๊ณผ์ ์์๋ Variable Environment ์ ์์ ํ ๋์ผํ๋, ์ดํ์ ๋ณ๊ฒฝ์ฌํญ์ด ์ค์๊ฐ์ผ๋ก ๋ณ๊ฒฝ๋๋ค.
- ThisBinding : ์ปจํ ์คํธ ๋ด์ ์๋ณ์๊ฐ ๋ฐ๋ผ๋ด์ผ ํ ๋์ ๊ฐ์ฒด
1 - 2. ์ฝ์คํ
// (a)
var a = 100;
function outer() {
function inner() {
console.log(a) // undefined
var a = 300;
}
inner(); // (b)
console.log(a); // 100
}
outer(); // (c)
console.log(a); // 1
(a)
์๋ฐ์คํฌ๋ฆฝํธ ํ์ผ์ด ์คํ๋๋ฉด(a), ์ ์ญ ์ปจํ ์คํธ๊ฐ ์ฝ ์คํ์ ๋ด๊น๋๋ค.
์คํ ์ปจํ ์คํธ๋ ์ด๋ค ํจ์๊ฐ ํธ์ถ๋๋ฉด ์ด๋ฆฌ์ง๋ง, ์ ์ญ ์ปจํ ์คํธ๋ ๋ณ๋์ ์คํ ๋ช ๋ น์ด ์์ด๋ ๋ธ๋ผ์ฐ์ ์์ ์๋์ผ๋ก ์คํ๋ฉ๋๋ค. ์ฆ ์๋ฐ์คํฌ๋ฆฝํธ ํ์ผ์ด ์ด๋ฆฌ๋ ์๊ฐ ์ ์ญ ์ปจํ ์คํธ๊ฐ ํ์ฑํ ๋๋ค๊ณ ์๊ฐํด๋ ๋ฉ๋๋ค.
(c)
๊ทธ ํ๋ก (c) ์์ outer() ํจ์๊ฐ ํธ์ถ๋๋ฉด์ ์คํ์ปจํ ์คํธ๊ฐ ์ด๋ฆฌ๋ฉฐ, outer() ํจ์๋ฅผ ์ฝ์คํ์ ๋ฃ์ต๋๋ค.
์ฝ์คํ์ ์๋จ์ outer ์ ์คํ ์ปจํ ์คํธ๊ฐ ๋์ด๊ฒ ๋์ด ์ ์ญ ์ปจํ ์คํธ๋ ๋ค์ ์๋จ์ ์ค๊ฒ ๋๊ธฐ ์ ๊น์ง ์ ์ ์ค๋จ๋ฉ๋๋ค.
(b)
outer ์ ์คํ์ปจํ ์คํธ๊ฐ ์ด๋ฆฌ๋ฉด์, outer ํจ์ ๋ด๋ถ์ ์ฝ๋๊ฐ ์์ฐจ์ ์ผ๋ก ์คํ๋ฉ๋๋ค.
๊ทธ๋ฌ๋ค (b) ์ง์ ์์ inner() ํจ์๊ฐ ํธ์ถ๋๋ฉด์ inner() ์ ์คํ์ปจํ ์คํธ๊ฐ ์ด๋ฆฌ๊ณ , ์ฝ์คํ์ ์ต์๋จ์ inner() ๊ฐ ์ฐจ์งํ๊ฒ ๋ฉ๋๋ค.
inner() ๋ด๋ถ์ ์ฝ๋๊ฐ ์์ฐจ์ ์ผ๋ก ์คํ๋๊ณ ๋๋ ํ ์ฝ์คํ์์ inner() ํจ์๋ pop ๋ฉ๋๋ค.
๋ค์ outer() ํจ์๊ฐ ์คํ ์ปจํ ์คํธ๋ฅผ ์ฐจ์งํฉ๋๋ค. ๋ง์ฐฌ๊ฐ์ง๋ก outer() ์ญ์ ๋ชจ๋ ์ฝ๋๋ฅผ ์คํํ๋ฉด ์ฝ์คํ์์ ๋น ์ ธ๋์ค๊ฒ ๋๋ฉฐ, ์ ์ญ ์ปจํ ์คํธ๋ง ๋จ์ ์ฝ์คํ์ ๋ง์ ์ ์ญ ์ปจํ ์คํธ๋ฅผ ์คํ์ํต๋๋ค.
2. Lexical Environment
Lexical Environment : ์๋ฐ์คํฌ๋ฆฝํธ ์ฝ๋์์ ๋ณ์๋ ํจ์ ๋ฑ์ ์๋ณ์๋ฅผ ์ ์ํ๋ ๊ฐ์ฒด
Lexical Environment ๋ environment Record ์ outer Environment Reference ๋ก ์ด๋ฃจ์ด์ ธ ์์ต๋๋ค.
2 - 1. environmentRecord ์ ํธ์ด์คํ
environment Record ๋ ํ์ฌ ์ปจํ ์คํธ ๋ด๋ถ์ ์๋ณ์ ์ ๋ณด๋ฅผ ์ ์ฅํฉ๋๋ค.
๋ง์น ์คํฌ๋ฆฝํธ๋ฅผ ์ฝ๋ฏ, ์ปจํ ์คํธ ๋ด๋ถ ์ ์ฒด๋ฅผ ์ฒ์๋ถํฐ ํ์ด๋๊ฐ๋ฉด์ ์์๋๋ก ์๋ณ์ ์ ๋ณด๋ฅผ ์์งํฉ๋๋ค.
์ปจํ ์คํธ๋ฅผ ๊ตฌ์ฑํ๋ ํจ์์ ๋งค๊ฐ๋ณ์ ์๋ณ์, ์ปจํ ์คํธ ๋ด๋ถ์ ํจ์, var, let, const ๋ฑ์ผ๋ก ์ ์ธ๋ ๋ณ์ ์๋ณ์๊ฐ environment Record ์ ์์ง๋์์ ํฌํจ๋ฉ๋๋ค.
์ปจํ ์คํธ ๋ด๋ถ์ ์๋ณ์๋ฅผ ์์งํ ๊ฒ๊ณผ ์คํ๋๋ ๊ฒ์ ๋ณ๊ฐ์ ์์ ์ ๋๋ค.
์ฆ ์ฝ๋๊ฐ ์คํ๋๊ธฐ๋ ์ ์, ์๋ฐ์คํฌ๋ฆฝํธ ์์ง์ ์ด๋ฏธ ํด๋น ์ปจํ ์คํธ์ ๋ณ์(์๋ณ์)๋ฅผ ๋ชจ๋ ํ์ ํ๊ฒ ๋๋๋ฐ ์ด๋ฅผ ํธ์ด์คํ ์ด๋ผ ๋ถ๋ฆ ๋๋ค.
2 - 1 - 0. Hoisting
ํธ์ด์คํ ์ ์ผ์ข ์ ๊ฐ์ ๊ฐ๋ ์ธ๋ฐ, ์ปจํ ์คํธ ๋ด๋ถ์ ๋ณ์๋ฅผ ๋์ด์ฌ๋ฆฐ๋ค๋ ์๋ฏธ๋ก ํํ ์๋ ค์ ธ ์์ต๋๋ค. ์๋ฐ์คํฌ๋ฆฝํธ ์์ง์ด ์๋ณ์๋ฅผ ๋ฏธ๋ฆฌ ํ์ ํ ๊ฒ์ ์ผ์ข ์ '๋์ด์ฌ๋ฆผ' ์ผ๋ก ํ์ํํ์ฌ ํํํ ๊ฐ๋ ์ ๋๋ค. (์๋ฐ์คํฌ๋ฆฝํธ ์์ง์ด ์ค์ ๋ก ์๋ณ์๋ฅผ ๋์ด์ฌ๋ฆฌ๋ ๊ฒ์ด ์๋, ํธ์์ ๊ทธ๋ ๊ฒ ์๊ฐํ์๊ณ ๋ถ์ธ ๊ฐ์ ๊ฐ๋ ์ผ๋ก ์๊ฐํ๋ฉด ๋ฉ๋๋ค.)
2 - 1 - 1. ํจ์ ์ ์ธ๋ฌธ๊ณผ ํจ์ ํํ์
environment Record ๋ ์ปจํ ์คํธ ๋ด๋ถ์ ์๋ณ์ ์ ๋ณด๋ฅผ ์์งํ๋ค๊ณ ํ์ต๋๋ค.
์ด๋ฅผ ์ ๋ ํ๋ฉฐ ํจ์์ ์ธ๋ฌธ๊ณผ ํจ์ ํํ์์ ์์๋ณด๊ฒ ์ต๋๋ค.
ํจ์ ์ ์ธ๋ฌธ : function ์ ์๋ถ๋ง ์กด์ฌํ๊ณ , ๋ณ๋์ ํ ๋น ๋ช ๋ น์ด ์์ต๋๋ค. ๋ฐ๋์ ํจ์๋ช ์ด ์กด์ฌํด์ผ ํฉ๋๋ค.
ํจ์ ํํ์ : function ์ ๋ณ๋์ ์๋ณ์์ ํ ๋นํ๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค. ํจ์๋ช ์ด ๋ฐ๋์ ์ ์๋ ํ์ ์์ด, ํ ๋น๋ ์๋ณ์๋ฅผ ๊ณง ํจ์๋ช ์ผ๋ก ๋ถ๋ฆ ๋๋ค.
// ํจ์ ์ ์ธ๋ฌธ, a ๊ฐ ๊ณง ํจ์๋ช
.
function a () {
...
}
// ํจ์ ํํ์, ๋ณ์๋ช
b ๊ฐ ๊ณง ํจ์๋ช
.
var b = function() { ... }
ํธ์ด์คํ ์ด๋ผ๋ ๊ฐ์์ ๊ฐ๋ ์ ํตํด ์๋ณ์๊ฐ ๋์ด์ฌ๋ ค์ง๋ ์์ ์ด ์ผ์ด๋๋ค๊ณ ์๊ฐํด๋ณด๊ฒ ์ต๋๋ค.
์๋ ์ฝ๋์์ (a) ๋ฅผ ํตํด ํจ์ ์ ์ธ๋ฌธ์ ์ ์ฒด๊ฐ ํธ์ด์คํ ๋๊ณ ,
ํจ์ ํํ์์ ๋ณ์ ์ ์ธ๋ถ(b)๋ง ํธ์ด์คํ ๋ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค.
// before hoisting
console.log(sum(1, 2));
console.log(multiply(3, 4));
function sum(a, b) { // ํจ์ ์ ์ธ๋ฌธ
return a + b;
}
var multiply = function (a, b) { // multiply: ํจ์ ํํ์
return a * b;
};
//////// after hoisting ////////
var sum = function sum(a, b) { // (a)
return a + b;
}
var multiply; // (b)
console.log(sum(1, 2));
console.log(multiply(3, 4));
multiply = function (a, b) {
return a * b;
};
ํธ์ด์คํ ์ด๋ผ๋ ๊ฐ์์ ๊ณผ์ ์ ํตํด ๊ฐ๊ฐ sum ๊ณผ multiply ๊ฐ console.log() ๋ณด๋ค ์๋ก ๋์ด์ฌ๋ ค์ก์ต๋๋ค. ์ด ๋ sum() ์ ํจ์ ์ ์ธ๋ฌธ์ด๊ธฐ ๋๋ฌธ์ ํ๋์ ๊ฐ์ผ๋ก์จ ๋์ด ์ฌ๋ ค์ง๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค.
sum ๋ณ์๊ฐ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์ ํ ๊ณณ์ ์ฐจ์งํ๋ฉฐ, sum ํจ์ ์ญ์ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์ ๋ค๋ฅธ ๊ณณ์ ์ ์ฅ๋ฉ๋๋ค.
sum ๋ณ์๊ฐ ์ ์ฅ๋ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์ sum ํจ์์ ์ฃผ์๋ฅผ ์ฐธ์กฐํ๋ฉฐ, ํด๋น ํจ์๊ฐ ํด๋น ๋ณ์์ ํ ๋น ๋ ๊ฒ์ ์ ์ ์์ต๋๋ค.
sum ํจ์๋ sum ๋ณ์์ ํ ๋น๋ผ๊ธฐ ๋๋ฌธ์ sum ํจ์์ ์ฃผ์๊ฐ์ sum ๋ณ์์ ๊ณต๊ฐ์ ํ ๋นํ์ฌ ๋ฐ๋ผ๋ณด๊ฒ ํฉ๋๋ค.
๋ฐ๋ฉด์ ํจ์ ํํ์์ธ multiply ๋ ๋ณ์ multiply ๋ง ํธ์ด์คํ ๋ ๋ฟ, ํด๋น ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์ด ์ฐธ์กฐํ ์ฃผ์๋ ๋น์ด์์ต๋๋ค. ์ด ์ํ๋ก console.log(multiply(3, 4)) ๋ฅผ ์ฐ์ผ๋ฉด 'multiply is not a function' ์ด๋ ์๋ฌ๋ฉ์์ง๋ง ์ถ๋ ฅ ๋ ๋ฟ์ ๋๋ค.
(b) ์์ ๋ณผ ์ ์๋ฏ multiply ๋ ๊ทธ์ ์๋ณ์์ ๋ถ๊ณผํ๊ธฐ ๋๋ฌธ์ ๋๋ค.
๋ค์ environmentRecord ์ ๊ด์ ์์ ์ดํด๋ณด๋ฉด, ํด๋น ์ปจํ ์คํธ์ environmentRecord ๋ sum ์๋ณ์์ ํจ์์ ์๋ถ๋ฅผ, ๊ทธ๋ฆฌ๊ณ ์๋ณ์ ๋ฟ์ธ multiply ๋ฅผ ์ ์ฅํ๋ค๊ณ ๋ณผ ์ ์์ต๋๋ค.
์ง๊ธ๊น์ง ๋งฅ๋ฝ์ ์ดํด๋ณด๋ฉด ์๋ฌ๋ฅผ ๋ด์ง ์๋ ํจ์ ์ ์ธ๋ฌธ์ด ์งฑ์งฑ ์๋๊ฐ? ํ๊ณ ์๊ฐํ์ค์๋ ์์ต๋๋ค.
ํ์ง๋ง ํ์ ์์๋ ๋๋ถ๋ถ ํจ์ ํํ์์ผ๋ก ์ฝ๋๋ฅผ ์์ฑํ๋ ๊ฒ์ ๋ณผ ์ ์๋๋ฐ, ๊ทธ ์ด์ ๋ฅผ ์์๋ณด๊ฒ ์ต๋๋ค.
2 - 1 - 2 ํจ์ ํํ์์ด ๋ ์์ ํ ์ด์
console.log(sum(1, 2)); // (a)
function sum(a, b) {
return a + b;
}
var a = sum(1, 2); // (b)
/// after 1000 line ///
function sum(a, b) {
return a + '+' + b + '=' + (x + y);
}
var c = sum(1, 2); // (c)
console.log(c) // (d)
์ ์ฝ๋์์ sum() ํจ์๋ ํจ์ ์ ์ธ๋ฌธ์ ํํ๋ก ์์ฑ๋์์ต๋๋ค. ๊ทธ๋ ๊ธฐ ๋๋ฌธ์ (a) ์์ ๋ฌด๋ฆฌ ์์ด sum(1,2) ์ ๊ฒฐ๊ณผ๊ฐ์ธ 3์ ์ถ๋ ฅํ ๊ฒ์ด๋ผ ์์ธกํ ์ ์์ต๋๋ค.
ํ์ง๋ง 1000 ์ค ์ดํ, ์ฝ๋๊ฐ ๋๋ฌด ๊ธธ์ด์ ธ ๊ธฐ์กด์ sum() ํจ์์ ์กด์ฌ๋ฅผ ์๊ณ ์ค์๋ก ๋์ผํ ์ด๋ฆ์ sum() ํจ์๊ฐ ์ฌ์ ์ ํ๋ค๊ณ ๊ฐ์ ํด๋ด ์๋ค. ๋ฌธ์์ด์ ๋ฆฌํดํ๋ ๋๋ฒ์งธ sum() ํจ์ ์ญ์, ํธ์ด์คํ ๋์ด ์๋ก ๋์ด์ฌ๋ ค์ง๋๋ฐ, ์ด ๋ ๊ธฐ์กด์ ์ซ์๋ฅผ ๋ฆฌํดํ๋ ํจ์์ ๋ด์ฉ์ ๋ฎ์ด๋ฒ๋ฆฌ๋ ์ํฉ(์ค๋ฒ๋ผ์ด๋)์ด ๋ฐ์ํฉ๋๋ค.
1000 ์ค ์ด์ ์ ์ฝ๋์์๋ ๋น์ฐํ (a) ์์ ์ซ์ํ ๊ฐ์ด ์ถ๋ ฅ๋ ๊ฒ์ด๋ผ ๋ฏฟ์์ง๋ง, ์ค๋ฒ๋ผ์ด๋ ๋ sum() ํจ์๋ก ์ธํ์ฌ (a) ์์๋ ๋ฌ๊ธ์๋ ๋ฌธ์์ด ๊ฐ์ด ์ถ๋ ฅ๋๋ ์ํฉ์ด ๋ฒ์ด์ง๊ฒ ๋ฉ๋๋ค. ์ค์๊ฐ์์ผ๋ก ์๋ฌ ๊ฒ์ถ๋ ๋์ง ์๊ธฐ ๋๋ฌธ์ ์ด๋ ๋ถ๋ถ์ด ๋ฌธ์ ์ธ์ง ๋ ์ฐพ๊ธฐ ํ๋ค์ด์ง๊ฒ ์ฃ ?
๊ทน๋จ์ ์ด์ง๋ง ํจ์ ์ ์ธ๋ฌธ์ด ๊ฐ์ง๋ ์ํ์ฑ์ ๋ณด์ฌ์ฃผ๋ ์์์์ต๋๋ค.
๋ง์ฝ ์์ ๊ฐ์ ์ํฉ์์ ํจ์ ํํ์์ด๋ผ๋ฉด ์ด๋ป๊ฒ ๋์๊น์?
ํจ์ ํํ์์ ๊ฒฝ์ฐ, ํจ์๊ฐ ํ ๋น๋ ๋ณ์๋ง ํธ์ด์คํ ๋๊ธฐ ๋๋ฌธ์ ๋ค๋ฅธ ํจ์๋ฅผ ์ค๋ฒ๋ผ์ด๋ํ ๊ฐ๋ฅ์ฑ์ด ์์ต๋๋ค.
console.log(sum(1, 2)); // (a) -- Uncaught Type Error: sum is not a function
var sum = function (a, b) {
return a + b;
}
var a = sum(1, 2); // (b)
/// after 1000 line ///
var sum = function(a, b) {
return a + '+' + b + '=' + (x + y);
}
var c = sum(1, 2); // (c)
console.log(c) // (d)
(a) ๋ถ๋ถ์์ ๊ณง๋ฐ๋ก ์๋ฌ๊ฐ ์ถ๋ ฅ๋๋ ๊ฒ์ ๋ณผ ์ ์๋๋ฐ, ํจ์ํํ์์ ๊ฒฝ์ฐ sum ๋ณ์ ์ ์ธ๋ถ๋ง ํธ์ด์คํ ๋์ด undefined ์ํ์ด๊ธฐ ๋๋ฌธ์ ๋๋ค.
๋น๋ก (a) ์์๋ ์๋ฌ๊ฐ ๋ฐ์ํ ์ ์์ง๋ง, ํด๋น ๋ถ๋ถ๋ง ์ง๋๋ฉด ํจ์ ์ ์ธ๋ฌธ์์ ๋ง์ฃผํ๋ ๋ฌธ์ ๋ฅผ ํผํ ์ ์์ต๋๋ค.
1000์ค ์ดํ์์ ๋์ผํ ์ด๋ฆ์ผ๋ก sum ํจ์๋ฅผ ์ ์ธํด๋, (b) ์ (c) ์์ ๊ฐ๋ฐ์๊ฐ ์๋ํ๋๋ก ๊ฐ์ ์ถ๋ ฅํ ์ ์์ต๋๋ค.
๋ง์ฝ ์์๋ก ํจ์ํํ์์ ๋ํ๋ธ๋ค๋ฉด, ๋์ผํ ์ด๋ฆ์ ํจ์์ ๋ํด Syntax Error ๋ฅผ ๋ฐ์ํ์ฌ, ์ฌ์ ์ ์๋ฌ๋ฅผ ๋ฐฉ์งํ ์๋ ์์ต๋๋ค.
๊ทธ ์๋์ sum() ํจ์์ ์ธ๋ฌธ์ ๊ฒฝ์ฐ ๊ทธ๋๋ก ์ค๋ฒ๋ผ์ด๋(๋๋ฒ์งธ sum ์ด ์ฒซ๋ฒ์งธ sum ์ ๋ฎ์ด๋ฒ๋ฆฐ๋ค) ๋๋๊ฒ์ ์ด์ ๋ ์ดํดํ ์ ์์ต๋๋ค.
์ ๋ฆฌ
1. ์ ์ญ๊ณต๊ฐ์ ํจ์๋ฅผ ์ ์ธํ๊ฑฐ๋, ๋๋ช ์ ํจ์๋ฅผ ์ค๋ณต ์ ์ธํ๋ ๊ฒฝ์ฐ๋ ์์ ํด์ผํฉ๋๋ค.
2. ์ ์ญ๊ณต๊ฐ์ ๋๋ช ์ ํจ์๊ฐ ์กด์ฌํ๋ ์ํฉ์ด๋๋ผ๋, ํด๋น ํจ์๋ค์ด ํจ์ ํํ์์ผ๋ก ์ ์๋๋ค๋ฉด ์ ๊ฐ์ ์๋ฌ ์ํฉ์ ํผํ ์ ์์ต๋๋ค.
3. const ์์์ ํจ์ ํํ์์ ํ ๋นํ๋ค๋ฉด, (ํ์ ๊ณผ์ ์์) ๋๋ช ์ ํจ์๋ฅผ ๋ง๋๋ ๋ฌธ์ ๋ฅผ ๋ฐฉ์งํ ์ ์์ต๋๋ค.
2 - 2. ์ค์ฝํ, ์ค์ฝํ ์ฒด์ธ
์ค์ฝํ scope : ์๋ณ์์ ์ ํจ๋ฒ์
์๋ฐ์คํฌ๋ฆฝํธ๋ ํจ์์ ์ํด ์ค์ฝํ๊ฐ ์ฃผ๋ก ๋ฐ์ํ๋๋ฐ, ES6 ๋ถํฐ๋ ๋ธ๋ก์ ์ํด์๋ ์ค์ฝํ ๊ฒฝ๊ณ๋ฅผ ๋ฐ์์ํฌ ์ ์์ต๋๋ค. ์ค์ฝํ ๊ฒฝ๊ณ๋ ์ด๋ค ์ํฉ์์ ์ฌ์ฉ๋ ๊น์?
์ค์ฝํ๋ ์๋ณ์์ ์ ํจ๋ฒ์๋ผ ํ์ต๋๋ค. ์ ํจ๋ฒ์๋ ์ ๊ทผํ ์ ์๋ ์์ญ ์ ๋๋ก ํ๊ฒ ์ต๋๋ค.
const a = "a"
const bScope = () => {
const b = "b"
...
}
์์ a๋ก ์ ์ธํ ์๋ณ์์ ์ค์ฝํ๋ ์ ์ญ๊ณต๊ฐ ๋ฟ๋ง ์๋๋ผ, ํ์ดํํจ์ bScope ๋ด๋ถ๊น์ง ์ ๊ทผํ ์ ์์ต๋๋ค.
์ฆ a ์๋ณ์์ ์ ํจ๋ฒ์๋ ์ ์ญ๊ณต๊ฐ + bScope() ๋ด๋ถ ๋ผ๊ณ ๋ณผ ์ ์์ต๋๋ค.
ํ์ง๋ง bScope() ๋ด๋ถ์์ ์ ์ธ๋ b ์๋ณ์๋, ํด๋น ํจ์ ์ธ๋ถ์์ ์ ๊ทผํ ์ ์์ต๋๋ค. b ์๋ณ์์ ์ ํจ๋ฒ์๋ ๋ฑ bScope() ๋ด๋ถ์ ๋๋ค.
2 - 2 - 1. ์ค์ฝํ, ์ค์ฝํ ์ฒด์ธ, outerEnvironmentReference
Lexical Environment ๋ outerEnvironmentReference ์ environmentRecord ๋ก ์ด๋ฃจ์ด์ ธ ์์ต๋๋ค.
๊ทธ ์ค outerEnvironmentReference ๋ ํธ์ถ๋ ํจ์๊ฐ ์ ์ธ๋ ๋น์์ LexicalEnvironment ๋ฅผ ์ฐธ์กฐํฉ๋๋ค.
์ด๋ฅผ ์กฐ๊ธ ํ์ด ์ค๋ช ํ๋ฉด, a ํจ์ ๋ด๋ถ์ b ํจ์๊ฐ ์ ์ธ๋ผ ์๋ค๋ฉด, b ํจ์์ outerEnvironmentReference ๋ a ํจ์์ LexicalEnvironment ๋ฅผ ์ฐธ์กฐํฉ๋๋ค. ์๋ํ๋ฉด b ํจ์๊ฐ ์ ์ธ๋ ๋น์, a ํจ์์ ์ค์ฝํ์ ์์๊ธฐ ๋๋ฌธ์ ๋๋ค.
๊ธ๋ก๋ ์ ์๋ฟ์ง ์์ต๋๋ค. ์ฝ๋๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
var a = 1;
var outer = () => {
var middle = () => {
console.log('(1)', a); // (1) undefined
var a = 3;
var inner = () => {
console.log('(2)', a); // (2) undefined
var a = 5;
}
inner();
}
middle();
console.log('(3)', a); // (3) 1
}
outer();
console.log('(4)', a); // (4) 1
middle ํจ์๋ outer ํจ์์ ๋ด๋ถ์์, inner ํจ์๋ middle ํจ์์ ๋ด๋ถ์์ ์ ์ธ๋์ด ์์ต๋๋ค.
outerEnvironmentReference ๋ฅผ ๋์ ํด์ ๋งํ๋ฉด,
middle ํจ์์ outerEnvironmentReference ๋ outer ํจ์์ LexicalEnvironment ๋ฅผ ,
inner ํจ์์ outerEnvironmentReference ๋ middle ํจ์์ LexicalEnvironment ๋ฅผ ์ฐธ์กฐํฉ๋๋ค.
๋ง์น ์ฐ๊ฒฐ๋ฆฌ์คํธ(linked list) ๊ฐ์ ํํ๋ฅผ ๋๋ ๊ฒ์ ๋ณผ ์ ์์ต๋๋ค.
๊ทธ๋ ๋ค๋ฉด outerEnvironmentReference ๊ฐ ์ฐธ์กฐํ๋ LexicalEnvironment ๊ฐ ์ด์จ๋ค๋ ๊ฑธ๊น์?
์ฐ์ middle ํจ์ ๋ด๋ถ์ ๊ทธ ๋ด๋ถ์์ ์ ์ธ๋ innerํจ์๋ฅผ ๋จผ์ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
middle ํจ์์ LexicalEnvironment ๋ ์ฐ์ ์๋ณ์ a ์ inner ํจ์๋ฅผ EnvironmentRecord ์ ๋ด์ต๋๋ค.
inner ํจ์์ LexicalEnvironment ๋ inner() ๋ด๋ถ์ ์๋ณ์ a ๋ฅผ EnvironmentRecord ์ ๋ด๊ณ , middle ํจ์์ LexicalEnvironment ๋ฅผ ์ฐธ์กฐํ์ฌ outerEnvironmentReference ์ ๋ด์ต๋๋ค.
inner() ํจ์์ ๋ด๋ถ์๋ a ์๋ณ์๋ฅผ ์ฝ์๋ก๊ทธ์ ์ถ๋ ฅํ๋ผ๊ณ ํ์ง๋ง, (ํธ์ด์คํ ๋) a ์๋ณ์์ ์ด๋ ํ ๊ฐ๋ (์์ง) ํ ๋น๋์ง ์์ ์ํ์ด๊ธฐ ๋๋ฌธ์ undefined ๋ฅผ ์ถ๋ ฅํ๊ฒ ๋ฉ๋๋ค.
inner() ํจ์ ๋ด๋ถ์ ์๋ณ์ a ๊ฐ ์๋ค๋ฉด, ์ธ๋ถ์์ ์ ์ธํ ๋์ผํ ์ด๋ฆ์ a ๋ณ์์๋ ์ ๊ทผํ ์ ์๊ณ , ์ด๋ฅผ ๋ณ์ ์๋ํ ๋ผ๊ณ ํฉ๋๋ค.
์ฌ๊ธฐ์ ๋ง์ฝ inner ํจ์ ๋ด๋ถ์ var a = 5 ๋ผ๋ ์ฝ๋๊ฐ ์์๋ค๋ฉด ์ด๋ป๊ฒ ๋์๊น์?
inner ํจ์ ๋ด๋ถ์ a ์๋ณ์๊ฐ ์์ผ๋ a ๋ฅผ ์ถ๋ ฅํ๋ ์ฝ์๋ก๊ทธ๋ ์ฌ์ ํ undefined๋ฅผ ์ถ๋ ฅํ ๊น์?
์ฌ๊ธฐ์ ์ค์ฝํ์ฒด์ธ๊ณผ outerEnvironmentReferece ๊ฐ ํจ๊ณผ๋ฅผ ๋ฐํํฉ๋๋ค.
// inner ํจ์ ๋ด๋ถ์ a๊ฐ ์ ์ธ๋์ง ์์ ๊ฒฝ์ฐ
var a = 1;
var outer = () => {
var middle = () => {
console.log('(1)', a); // (1) undefined
var a = 3;
var inner = () => {
console.log('(2)', a); // (2) 3
}
inner();
}
middle();
console.log('(3)', a); // (3) 1
}
outer();
console.log('(4)', a); // (4) 1
(2) ๋ถ๋ถ์์ a ์ ๊ฐ์ undefined ๊ฐ ์๋ 3์ด ์ถ๋ ฅ๋ฉ๋๋ค.
๋์น ์ฑ์ จ๊ฒ ์ง๋ง, innerํจ์์ outerEnvironmentReference๊ฐ middle ํจ์์ LexicalEnvironment ๋ฅผ ์ฐธ์กฐํ๊ธฐ ๋๋ฌธ์, middle์ LexicalEnvironment ์ ์ ์ฅ๋ a์ ๊ฐ์ธ 3์ ์ถ๋ ฅํ๊ฒ ๋๋ ๊ฒ์ ๋๋ค.
์์ ์ ๋ฒ์ ๋ฐ๊นฅ์ ์๋ณ์ a ์ ์ ๊ทผํ๋ค๊ณ ์๊ฐํ ์๋ ์์ง๋ง, ์ธ๋ถ ์ค์ฝํ์์ ๋ด๋ถ๋ก ์ ๊ทผํ ๊ฒ์ผ๋ก ๋ณด๋ ๊ฒ์ด ์ฌ๋ฐ๋ฅธ ๊ด์ ์ ๋๋ค. inner ๋ด๋ถ์ ์๋ ์๋ณ์๋ฅผ ๋ฐ๊นฅ์์๋ ์ฐธ์กฐํ ์ ์์ง๋ง, ์ญ์ผ๋ก inner ์ธ๋ถ์ ์๋ณ์๋ฅผ inner ๋ด๋ถ๋ก ๊ฐ์ ธ์ ์ฌ์ฉ(์ ๊ทผ)ํ๋ ๊ฒ์ ๊ฐ๋ฅํ๊ธฐ ๋๋ฌธ์ ๋๋ค.
์ ๋ฆฌ ๋ฐ ์์ฝ
1. ์คํ ์ปจํ ์คํธ๋ ์คํ๋๋ ์ฝ๋์ ์ ๊ณต๋๋ ํ๊ฒฝ ์ ๋ณด๋ค์ ๋ชจ์๋์ ๊ฐ์ฒด์ ๋๋ค.
2. ์คํ ์ปจํ ์คํธ์ LexicalEnvironment ๋ environmentRecord ์ outerEnvironmentReference ๋ก ๊ตฌ์ฑ๋ผ ์์ต๋๋ค.
3. environmentRecord ๋ ๋งค๊ฐ๋ณ์๋ช , ๋ณ์ ์๋ณ์, ํจ์๋ช ๋ฑ์ ์์งํ๋ฉฐ, outerEnvironmentReference ๋ ์ง์ ์ปจํ ์คํธ์ LexicalEnvironment ์ ๋ณด๋ฅผ ์ฐธ์กฐํฉ๋๋ค.
4. ๋ณ์ ์ ์ธ๊ณผ ๊ฐ ํ ๋น์ด ๋์์ ์ด๋ฃจ์ด์ง ๋ฌธ์ฅ์ ์ ์ธ๋ถ๋ง์ ํธ์ด์คํ ํ๊ณ , ํ ๋น ๊ณผ์ ์ ์๋ ์๋ฆฌ์ ๋จ์์์ต๋๋ค. ์ด ๋๋ฌธ์ ํจ์ํํ์๊ณผ ํจ์์ ์ธ๋ฌธ์ ํธ์ด์คํ ์ฐจ์ด๊ฐ ๋ฐ์ํฉ๋๋ค.
5. ์ด๋ค ๋ณ์์ ์ ๊ทผํ ๋, ํ์ฌ ์ปจํ ์คํธ์ LexicalEnvironment ๋ฅผ ํ์ํ์ฌ ํด๋น ๊ฐ์ ๋ฐ๊ฒฌํ๋ฉด ๊ทธ ๊ฐ์ ๋ฐํ, ๊ทธ๋ฌ์ง ๋ชปํ ๋ outerEnvironmentReference ์ ๋ด๊ธด LexicalEnvironment ์์ ํด๋น ๋ณ์๋ฅผ ์ฐพ๋ ๊ณผ์ ์ ๋ฐ๋ณตํฉ๋๋ค.(์ค์ฝํ ์ฒด์ธ) ๋ง์ฝ ์ ์ญ ์ปจํ ์คํธ๊น์ง ํด๋น ๋ณ์๋ฅผ ์ฐพ์ง ๋ชปํ๋ฉด undefined ๋ฅผ ๋ฐํํฉ๋๋ค.
'๐ Book > Core Javascript' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
์๋ฐ์คํฌ๋ฆฝํธ ๋ฐ์ดํฐ ํ์ (0) | 2021.08.14 |
---|