๐ JavaScript์ ์๋ฃํ๊ณผ JavaScript๋ง์ ํน์ฑ์ ๋ฌด์์ผ๊น ?
๐ JavaScript๋ ๋์จํ ํ์ (loosely typed)์ ๋์ (dynamic) ์ธ์ด์ ๋๋ค.
Javascript๋ณ์๋ ๋ง๋ค์์๋ ๋ฐ๋ก ํน์ ํ์ ๊ฐ์ผ๋ก ์ฐ๊ฒฐ๋์ง ์์ผ๋ฉฐ ์ด๋ค ํ์ ์ ๊ฐ์ผ๋ก ํ ๋นํ ์๋ ์์ผ๋ฉฐ ๋ํ ์ฌํ ๋น ํ ์๋ ์์ต๋๋ค. ํํ ์๋ฐ์คํฌ๋ฆฝํธ๋ untyped ๋๋ weakly-typed์ธ์ด๋ผ๊ณ ๋ ๋ง์ด ๋ถ๋ฆ ๋๋ค.
์๋ฅผ ๋ค์ด "12345" ๋ผ๋ ๋ฌธ์์ด๊ณผ 1์ด๋ผ๋ ์ซ์๋ฅผ ๊ณฑํ๊ฒ ๋๋ฉด ์๋๋ ๋ฌธ์์ด์ int๋ผ๋ type์ ์๋ฐ์์๋ ์ค์ ํด์ฃผ๊ฒ ์ง๋ง ์๋ฐ์คํฌ๋ฆฝํธ์์๋ ๊ทธ๋ฅ "12345 * 1 === ํด๋ ๊ฒฐ๊ณผ๊ฐ์ 12345๋ก ์ซ์๋ก ๋์ค๊ฒ ๋ฉ๋๋ค. ๊ทธ๋ฌ๋ฏ๋ก ์๋ฐ์คํฌ๋ฆฝํธ๋ weakly-typed๋ผ๊ณ ๋ณผ์ ์์ง์. ๊ทธ๋ฆฌ๊ณ ์๋ฐ์คํฌ๋ฆฝํธ์์๋ String a = "blah"; ๋๋ var a:String = 'blah' ์ด๋ฐ์์ผ๋ก ํ์ ์ ์ค ์๊ฐ ์๋ ํํ์ ๋๋ค. ์ด๋์ untyped ์ธ์ด๋ผ๊ณ ๋ ๋ถ๋ฆฝ๋๋ค.
๋์ (dynamic)์ธ์ด๋ผ๋ ๊ฒ์
x = 12345; // number
x = "string"; // string
x = { key: "value" }; // object
์ด๋ฐ์์ผ๋ก ์์๋ ์ธ๊ธํ๋ฏ์ด ๋ณ์๋ช ์ ๋ฐ๋ก ์ง์ ํด์ฃผ์ง ์์๋ ๋ค์ํ ํ์ ์ ์ค์ ์๋ค๋๊ฒ์ด ๊ฐ์ฅ ํฐ ์๋ฐ์คํฌ๋ฆฝํธ์ ํน์ง์ด๋ผ๊ณ ํ ์ ์์ต๋๋ค.
๐ JavaScript ํ๋ณํ
์๋ฐ์คํฌ๋ฆฝํธ๋ ๋งค์ฐ ์ ์ฐํ ์ธ์ด์ ๋๋ค. ๊ทธ๋ฌ๋ฏ๋ก ๋๋ก๋ ์๋ฐ์คํฌ๋ฆฝํธ ์์ง์ด ํ์์ฌ๋ถ์ ๋ฐ๋ผ '์์์ ๋ณํ' ๋๋ ๊ฐ๋ฐ์์ ์๋์ ๋ฐ๋ผ '๋ช ์์ ๋ณํ'์ ์คํํฉ๋๋ค.
๐ฅ ์์์ ๋ณํ
์์์ ๋ณํ์ด๋ ์๋ฐ์คํฌ๋ฆฝํธ ์์ง์ด ํ์์ ๋ฐ๋ผ ์๋์ผ๋ก ๋ฐ์ดํฐ ํ์ ์ ๋ณํ์ํค๋๊ฒ
ex)
์ฐ์ ์ฐ์ฐ์ : ๋ํ๊ธฐ ์ฐ์ฐ์(+)๋ ์ซ์๋ณด๋ค ๋ฌธ์์ด์ด ์ฐ์ ์ ๋๊ธฐ ๋๋ฌธ์ ์ซ์ํ์ด ๋ฌธ์ํ์ ๋ง๋๋ฉด ๋ฌธ์ํ์ผ๋ก ๋ณํ๋๋ค.
number + number // number
number + string // string
string + string // string
string + boolean // string
number + boolean // number
๊ทธ ์ธ ์ฐ์ฐ์: (-, *, /, %)๋ ์ซ์ํ์ด ๋ฌธ์ํ๋ณด๋ค ์ฐ์ ์ ๋๊ธฐ ๋๋ฌธ์ ๋ํ๊ธฐ ์ฐ์ฐ์์ ๊ฐ์ ๋ฌธ์ํ ๋ณํ์ด ์ผ์ด๋์ง์๋๋ค.
string * number // number
string * string // number
number * number // number
string * boolean //number
number * boolean //number
๐ฅ ๋ช ์์ ๋ณํ
๋ช ์์ ๋ณํ์ด๋ ๊ฐ๋ฐ์๊ฐ ์๋๋ฅผ ๊ฐ์ง๊ณ ๋ฐ์ดํฐ ํ์ ์ ๋ณํ์ํค๋๊ฒ
ex)
ํ์ ์ ๋ณ๊ฒฝํ๋ ๊ธฐ๋ณธ์ ์ธ ๋ฐฉ๋ฒ์ 'Object(), String(), Boolean(), Number()์ ๊ฐ์ ํจ์๋ฅผ ์ด์ฉํ๊ฒ ๋๊ธดํ๋๋ฐ new ์ฐ์ฐ์๊ฐ ์์๊ฒฝ์ฐ ์ฌ์ฉํ ํจ์๋ ํ์ ์ ๋ณํํ๋ ํจ์๋ก์จ ์ฌ์ฉ๋๋ค.
์ฌ๋ฌ ์๋ฃํ์ ์ซ์ํ์ ์ผ๋ก ๋ณํํ๋ ๋ฐฉ๋ฒ
1. Number()
2. parseInt()
3. parseFloat()
4. +()
์ฌ๋ฌ ์๋ฃํ์ ๋ฌธ์ํ์ ์ผ๋ก ๋ณํํ๋ ๋ฐฉ๋ฒ
1. String()
2. .toString()
3. .toFixed() -> ์ธ์๋ฅผ ๋ฃ์ผ๋ฉด ์ธ์๊ฐ๋งํผ ๋ฐ์ฌ๋ฆผํ์ฌ ์์์ ์ ํํํ๋ฉฐ ์์์ ์ ๋์น๋ ๊ฐ์ด ์ธ์๋ก ๋ค์ด์ฌ๋ '0'์ผ๋ก ๊ธธ์ด๋ฅผ ๋ง์ถ ๋ฌธ์์ด์ ๋ฐํ
์ฌ๋ฌ ์๋ฃํ์ ๋ถ๋ฆฐ(Boolean)ํ์ ์ผ๋ก ๋ณํํ๋ ๋ฐฉ๋ฒ
1. Boolean()
๐ '=='์ '==='์ ์ฐจ์ด์
์๋ฐ์คํฌ๋ฆฝํธ๋ ์๊ฒฉํ ๋น๊ต์ ์ ํ๋ณํ ๋น๊ต๋ฅผ ๋ชจ๋ ์ง์ํ๊ธฐ ๋๋ฌธ์ ์ด๋ค ์ฐ์ฐ์๊ฐ ์ด๋ค ๋น๊ต์กฐ๊ฑด์ ์ฌ์ฉ๋๋์ง๊ฐ ์ค์ํ๋ค. ==๋ ๋ณ์ ๊ฐ์ ๊ธฐ๋ฐ์ผ๋ก ์ ํ์ ์์ ํ๋๋ฐ์ ๋นํด ===๋ ๋ณ์ ์ ํ์ ๊ณ ๋ คํฉ๋๋ค.
๋ ์ฐ์ฐ์๋ ๊ฐ์ด ์ผ์นํ ๊ฒฝ์ฐ true๋ฅผ returnํ๋ฉฐ ๊ฐ์ด ์ผ์นํ์ง ์์ผ๋ฉด false๋ฅผ returnํ๋ค.
๐ญ'==' ๋ ์ฐ์ฐ์๋ฅผ ์ด์ฉํ์ฌ ์๋ก ๋ค๋ฅธ ์ ํ์ ๋ ๋ณ์์ ๊ฐ์ ๋น๊ต
-> ํนํ ๋ ํผ์ฐ์ฐ์์ ๊ฐ์ด ํ์ ์ด ๋ค๋ฅผ ๊ฒฝ์ฐ์๋ ์ผ๋ถ ํผ์ฐ์ฐ์์ ํ์ ์ ๋ณํ ํ์ ๊ฐ์ ๋น๊ตํฉ๋๋ค.
ํ์ ์ ๋ฐ๋ก ๋น๊ตํ์ง ์์ผ๋ฏ๋ก ===์ฐ์ฐ์์ ๋นํด ๋์จํ๋ค.
ex)
10 == '10' // ๋ฌธ์์ด์ ์ซ์๋ก ๋ณํ ํ ๊ฐ์ ๋น๊ต
true == 1 // ๋ถ๋ฆฌ์ธ ๊ฐ์ 1๋ก ๋ณํ ํ ๊ฐ์ ๋น๊ต
true == '1' // ๋ถ๋ฆฌ์ธ ๊ฐ์ 1๋ก ๋ณํํ๋ฉด 1 == '1'์ด ๋์ง๋ง ๋ฌธ์์ด '1'์ ์ซ์๋ก ๋ณํ ํ ๊ฐ์ ๋น๊ต true๋ฅผ ๋ฐํ
true == 'true' // 1 == 'true'๊ฐ ๋์ง๋ง ๋ฌธ์์ด 'true'๋ ์ซ์๋ก ๋ณํ ๋ถ๊ฐ๋ฅ ํ๊ธฐ์ 1=='true'๋ก ๋์ด false๋ฅผ return
null == undefined // null๊ณผ undefined๋ ๋ค๋ฅด์ง๋ง ==์์๋ true๋ฅผ ๋ฐํ
๐ญ'==='๋ ์๊ฒฉํ ๋น๊ต๋ฅผ ํ๋ค, ํนํ ๊ฐ์ด๋ ์๋ฃํ์ด true์ผ๋
-> ํ์ ์ ๋ณํํ์ง ์์ผ๋ฏ๋ก ํ์ ์ด ์ธํ ๋์ด์์ง ์๋ค๋ฉด false๋ฅผ ๋ฐํ. NaN์ ์๊ธฐ ์์ ์ ํฌํจํ์ฌ ์ด๋ ํ ๊ฐ๊ณผ๋ ์ผ์น ํ์ง ์์. ์ฆ NaN์ด ์กด์ฌํ ๊ฒฝ์ฐ ํญ์ false๋ฅผ returnํ๊ฒ ๋ฉ๋๋ค.
-> ์ ํํ ๋ฌธ์์ด์ ๋น๊ตํ ๋์๋ localeCompare ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข์ต๋๋ค ์๋ํ๋ฉด ๋ฌธ์์ด์ด ๋์ผ๋ก ๋ณด๋ ๊ฒ๊ณผ๋ฌ๋ฆฌ ์ธ์ฝ๋ฉ ๋ฐฉ์์ด ๋ค๋ฅผ ์๋ ์๊ธฐ ๋๋ฌธ์ ๋๋ค.
ex)
10 === 10 // true
10 === '10' // false
true === 1 // false
true === 'true' // false
null === undefined // false
NaN === NaN // false
๐ ๋์จํ ํ์ (loosely typed)์ ๋์ (dynamic) ์ธ์ด์ ๋ฌธ์ ์ ๊ณผ ๋ณด์ํ ์ ์๋ ๋ฐฉ๋ฒ์ ๋ฌด์์ด ์์๊น?
๐ญ Javascript๋ ๋ณ์ ์์ฑ ์ ์์ ๋ณ์์ ํ์ ์ ๋ฏธ๋ฆฌ ์ ์ธํ์ง ์์๋ ๋๋ ์ฅ์ ์ ์์ง๋ง ๋ง์ ๊ธฐ๋ฅ ๋ช ์ธ์์ API๊ฐ ์ค๊ณ ๊ฐ๋ ๋ํํ๋ก์ ํธ ๋๋ ํ์ ํ๋ก์ ํธ๋ฅผ ์งํ์์ ๊ฐ๊ฐ์ ๋ณ์ ํ์ ์ด ์ฌ๋ฐ๋ฅธ์ง ์ฒดํฌํ๋ ๊ฒ์ด ๊ต์ฅํ ๊น๋ค๋กญ๊ธฐ ๋๋ฌธ์ ๋ฐฐํฌํ์๋ ์์ํ์ง ๋ชปํ ๋ฌธ์ ๋ฅผ ์ง๋ฉดํ ์ ์์ต๋๋ค.
// ๋ฐฑ์๋ ๊ฐ๋ฐ์๊ฐ ์ ๋ฌํ ๋ช
์ธ์
{
id: number,
product_name: string,
price: number
}
// ํ๋ฐํธ ๊ฐ๋ฐ์๊ฐ ์ ๋ฌํ ๋ฐ์ดํฐ
{
id: 12345,
product_name: 'water melon',
price: '12,000'
}
์ด ์์์์ ๋ณด๋ฏ์ด id๊ฐ ์ซ์๋ก ์ค๊ณ product_name์ ๋ฌธ์์ด๋ก ์ค๋ ๊ฒ๊น์ง๋ ๊ด์ฐฎ์ผ๋ price๋ ์ซ์๋ก ์์ผํ๋๋ฐ ํ๋ฐํธ ๊ฐ๋ฐ์๊ฐ ์ ๋ฌํ ๋ฐ์ดํฐ๋ ๋ฌธ์์ด๋ก ๋ณด๋ด๋ฏ์ด type error๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค.
๐ญ์ด๋ฐ ๋ฌธ์ ์ ์ ๋ณด์ํ๊ธฐ ์ํด ์ ์ ํ์ ์ฒดํฌ์ ๊ฐ๋ ฅํ ๋ฌธ๋ฒ์ ์ถ๊ฐํ Typescript๋ฅผ ์ด์ฉํ์ฌ ๋ฌธ์ ์ ์ ํด๊ฒฐ๊ฐ๋ฅํฉ๋๋ค.
๐ฅ Typescript๋ Javascript์ ํ์ ์ ๋ถ์ฌํ ์ ์ ํ์ ์ธ์ด์ ๋๋ค. Typescript๋ฅผ ๋ธ๋ผ์ฐ์ ์์ ์คํํ ์ ํ์ผ์ ๋ณํํ๋ ํธ๋์ค ํ์ผ ๊ณผ์ (์ผ์ข ์ ์ปดํ์ผ ๊ณผ์ )์ ๊ฑฐ์น๋ฉฐ ์ฌ์ฉํ๊ฒ ๋ฉ๋๋ค. ์ปดํ์ผ ๊ฐ์ ๊ฒฝ์ฐ๋ ํ ์ธ์ด๋ก ์์ฑ๋ ์์ค ์ฝ๋๋ฅผ ๋ค๋ฅธ ์ธ์ด๋ก ๋ณํํ๋ ๊ฒ์ด๋ฉฐ ํธ๋์ค ํ์ผ ๊ณผ์ ์ด๋ ์์ฑ๋ ์์ค์ฝ๋์ ๋น์ทํ ์์ค์ ๋ค๋ฅธ ์ธ์ด๋ก ๋ณํํ๋ค๋๊ฒ ํฐ ์ฐจ์ด์ ๋๋ค. ์ฌ๊ธฐ์๋ Typescript๋ฅผ ํธ๋์คํ์ผํ๋ฉด Javascript๊ฐ ์ถ๋ ฅ๋๋ ๊ฒ์ ๋๋ค. ๊ณต์์ ์ผ๋ก๋ ์ปดํ์ผ ๋๋ค๊ณ ๋๊ฐ์ด ํํ์ ํฉ๋๋ค.
๐ฅ Typescript ๊ฐ์ ์ ์ ํ์ ์ธ์ด๋ ๋ฐํ์ ์ ์ ํ์ ์ด ์ฌ๋ฐ๋ฅธ์ง์ ๋ํ ๊ฒ์ฌ๋ฅผ ์ํํ๊ฒ ๋๋ฉฐ ๋์ ํ์ ์ธ์ด๋ ๋ฐํ์์ ํ๋ก๊ทธ๋จ์ ํ์ ์ด ์ฌ๋ฐ๋ฅธ์ง์ ๋ํ ๊ฒ์ฌ๋ฅผ ์คํํ๋ค ์ฆ ์ ์ฒ๋ฆฌ ํ ์คํ๊ณผ ์ ์คํ ํ ์ฒ๋ฆฌ๋ผ๋ ์ฐจ์ด์ ์ด ์์ต๋๋ค.
์ด๋ ๊ฒ ๋๋ฉด ๋ํผ๋ฐ์ค ์ค๋ฅ๋ฅผ ์ผ์ผํค๋ ์ฝ๋๊ฐ ์กด์ฌํ ์ Typescript๋ ์ปดํ์ผ ๊ณผ์ ์์ ์ค๋ฅ๋ฅผ ์ถ๋ ฅํ๋ ๋ฐ๋ฉด์ Javascript๋ ํด๋น ๊ตฌ๋ฌธ์ด ์คํ๋๋ ์์ ์์ ์ค๋ฅ๋ฅผ ์ถ๋ ฅํ๊ฒ ๋ฉ๋๋ค.
๐ undefined์ null์ ๋ฏธ์ธํ ์ฐจ์ด
๐ญ undefined๋ ๋ณ์์ค์ ์กด์ฌํ์ง ์๋๋ค๋ผ๋ ๊ฒ์ ์๋ฏธํ๋ฉฐ ์ด๋ค ๊ฒ์ผ๋ก๋ ์ค๋ช ๋์ง ์๋ ๋ณ์๋ฅผ ์๋ฏธํฉ๋๋ค.
๐ญ null์ ๋ณ์์ค์ ์ค๋ช ์ ๋์ง๋ง ๊ฐ์ด ๋น ์ ธ์๋ ๊ฒฝ์ฐ๋ฅผ ์๋ฏธํฉ๋๋ค
ex)์์
let a;
console.log(a); // undefined
let b = null;
console.log(b); // null
๋ณ์๊ฐ undefined์ผ์ง null์ผ์ง ๊ตฌ๋ณํ ๋๋ == ๋๋ ===๋ฅผ ์ธ์ ์๋๋ฐ == ๊ฐ์ ๊ฒฝ์ฐ๋ ๋์จํ๊ฒ ๋น๊ตํ๊ธฐ ๋๋ฌธ์ undefined์ null์ ๋๊ฐ์ด true๋ก ๋ฆฌํดํด ์ค๋๋ค. ๊ทธ๋์ ๋น๊ตํด์ค๋
//a = undefined variable
let a;
if (a == null) {
console.log('Null or undefined value!');
} else {
console.log(a);
}
์ด๋ ๊ฒ ํ๋ฒ์ ํ๊ธฐ๋ฅผ ํด์ค์์์ต๋๋ค null์ด๋ undefined์ผ๋ true๋ฅผ ๋ฆฌํดํด์ค ํ ๋
ํ์ง๋ง ===๋ฅผ ์ด๋ค๋ฉด ์๋ก null๊ณผ undefined์์ type์ ๋ฐ๋ก ๋น๊ตํด์ฃผ๋๋ฐ ์๋ก ๊ฐ์ง ์๊ธฐ ๋๋ฌธ์ false๋ฅผ ๋ฆฌํดํด์ค๋๋ค.
๊ทธ๋ฌ๋ฏ๋ก ๊ฐ๊ฐ์ด null์ธ์ง undefined์ธ์ง ํ๊ธฐ๋ฅผ ๊ตฌ๋ถ์ง์ด์ค์ ์ธ๋ ์ข์ต๋๋ค.
let a;
if (a === null) {
console.log('Null Value!');
} else if (a === undefined) {
console.log('Undefined Value!');
}
๐ JavaScript ๊ฐ์ฒด์ ๋ถ๋ณ์ฑ์ด๋ ?
๐ ๊ธฐ๋ณธํ ๋ฐ์ดํฐ์ ์ฐธ์กฐํ ๋ฐ์ดํฐ
๐ญ๊ธฐ๋ณธํ๋ฐ์ดํฐ ํ์ (Primitive Type)
๊ธฐ๋ณธํ ํ์ ์ ์ข ๋ฅ์๋ ์ซ์(Number), ๋ฌธ์์ด(String), ๋ถ๋ฆฌ์ธ(Boolean), null, undefined, ์ฌ๋ณผ(Symbol) ์ด ์์ต๋๋ค.
* Symbol ๊ฐ์๊ฒฝ์ฐ๋ ES6์ ์ถ๊ฐ, ๊ฐ์ฒด ์์ฑ์ ๋ง๋๋ ๋ฐ์ดํฐ ํ์ ์ ๋๋ค
๊ธฐ๋ณธํ ๋ฐ์ดํฐ๋ ๊ฐ์ ๊ทธ๋๋ก ํ ๋นํ๋ฉฐ ๋ฉ๋ชจ๋ฆฌ์์ ๊ณ ์ ๋ ํฌ๊ธฐ๋ก ์ ์ฅ์ด ๋๊ณ ์์๋ฐ์ดํฐ ๊ทธ ๊ฐ ๊ทธ ์์ฒด๋ฅผ ๋ณด๊ดํ๋ฏ๋ก ๋ถ๋ณ์ ์ธ ๋ฐ์ดํฐ์ ๋๋ค.
๊ฐ์ ๋ฐ์ดํฐ๋ ํ๋์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ฌ์ฉํ๊ฒ ๋ฉ๋๋ค(์ฌ์ฌ์ฉ ๊ฐ๋ฅ)
์๋ฆฌ๋ ๊ธฐ๋ณธํ ๋ฐ์ดํฐ๊ฐ
var a;
var b = 'abc';
var c = b;
//์๋ก ํ ๋นํ๋ ค๋ ๋ถ๋ถ
a = 10;
b = false;
๋ณ์๋ช | a | b | c | d |
์ฃผ์ | @1 | @2 | @3 | ... |
์ฃผ์ | 1 | 2 | 3 | ... |
๋ฐ์ดํฐ | 10 | false | false | ... |
๋ณ์ a๋ 1๋ฒ ์์ญ, b๋ 2๋ฒ ์์ญ, c๋ 3๋ฒ์์ญ์ ํด๋น์ฃผ์๋ฅผ ํ๋ณดํ๊ณ ํด๋น์ฃผ์๋ฅผ ๋ณ์๋ช ๊ณผ ๋งตํ์ ์ํต๋๋ค.
๊ธฐ์กด๋ณ์๋ช ์ ์๋ก ํ ๋นํ๊ฒ ๋ ๊ฒฝ์ฐ์๋ ์๋ก์ด ๋ณ์๋ ๋ณ๋์ ๊ณต๊ฐ์ ํ๋ณดํ๊ณ ๋ถ๋ฆฌ์ธ๊ฐ์ ํตํด ๊ธฐ์กด ๋ณ์์ ๋์ ๋๋ ๊ตฌ์กฐ์ ๋๋ค.
var c = 20; ์ด๋ฐ์์ผ๋ก ํ๋ฉด 3์ ์์น์ ๋ฐ์ดํฐ false ๋ถ๋ถ์ด 20์ผ๋ก ๋ณ๊ฒฝ์ด๋ฉ๋๋ค.
๐ญ ์ฐธ์กฐํ๋ฐ์ดํฐ ํ์ (Reference Type)
์ฐธ์กฐํ๋ฐ์ดํฐ ํ์ ์๋ ๊ฐ์ฒด(Object), ๋ฐฐ์ด(Array), ํจ์(Function), ์ ๊ทํํ์(RegExp), Map, WeakMap, Set, WeakSet ๋ฑ์ด ์์ต๋๋ค.
๐ ๋ถ๋ณ ๊ฐ์ฒด(Immutable Object)๋ฅผ ๋ง๋๋ ๋ฐฉ๋ฒ
๐ญ ์ํ๊ฐ์ ์์ ํ ์ ์๋ ๊ฐ์ฒด ๋๋ ๊ฐ์ฒด๋ฅผ ์ฒ์ ์์ฑ ํ์๋ ๊ฐ์ฒด๊ฐ ๊ฐ์ง๋ ์ํ๋ฅผ ๋ณ๊ฒฝํ ์ ์๋ ๊ฒ์ ์๋ฏธ
๐ญ ๋ถ๋ณ๊ฐ์ฒด๋ ์ํ๊ฐ ๋ณํ์ง ์๊ธฐ ๋๋ฌธ์ ๋จ์
๐ญ Multi Threading ํ๊ฒฝ์์ Thread Safety๋ฅผ ๋ณด์ฅ ๋ฐ ์์๋ก์ Cache ์ฌ์ฉํ๊ธฐ๋ ์ฉ์ด
์๋ฐ์คํฌ๋ฆฝํธ์์ ๋ถ๋ณ๊ฐ์ฒด๋ฅผ ๋ง๋ค ์ ์๋ ๋ฐฉ๋ฒ์ ๊ธฐ๋ณธ์ ์ผ๋ก 2๊ฐ์ง๊ฐ ์์ต๋๋ค
1. const
2. Object.freeze()
๐ฅ const
ES6 ๋ฌธ๋ฒ๋ถํฐ let๊ณผ const๋ฅผ ์ง์์ ํ๋ฉฐ const ํค์๋๋ ๋ณ์๋ฅผ ์์๋ก ์ ์ธ ๊ฐ๋ฅ. ์ผ๋ฐ์ ์ผ๋ก ์์๋ก ์ ์ธ๋ ๋ณ์๋ ๊ฐ์ ๋ฐ๊พธ์ง ๋ชปํ๋ ๊ฒ์ผ๋ก ์๋ ค์ ธ ์๋ค.
๊ทธ๋ฐ๋ฐ ์์๋ก ์ ์ธํ ๊ฐ์ฒด๋ ๋ถ๋ณ๊ฐ์ฒด์ธ๊ฐ?
์๋ฅผ๋ค์ด
const exam = {};
exam.name = "yong";
console.log(exam); // {"yong"}
const๋ ํ ๋น๋ ๊ฐ์ด ์์๊ฐ ๋๋ ๊ฒ์ด ์๋ ๋ฐ์ธ๋ฉ๋ ๊ฐ์ด ์์๊ฐ ๋๋ ์ฌ๊ธฐ์๋ exam ๋ณ์๊ฐ ์์๊ฐ ๋๊ธฐ ๋๋ฌธ์ constํค์๋๋ก ์ ์ธ๋ exam ๋ณ์์๋ ๊ฐ์ฒด ์ฌํ ๋น์ ๋ถ๊ฐ๋ฅํ์ง๋ง ๊ฐ์ฒด์ ์์ฑ์ ๋ณ๊ฒฝ ๊ฐ๋ฅ
๊ฐ์ฒด ์ฌํ ๋น์ด ๋ถ๊ฐ๋ฅํ ์ด์
๋ณ์์ ๊ฐ ์ฆ ๊ฐ์ฒด ์ฌ์ด์ ๋ฐ์ธ๋ฉ ์์ฒด๊ฐ ๋ณ๊ฒฝ์ด ๋๊ธฐ ๋๋ฌธ์ ์์์ธ exam ๋ณ์๋ ์ฌํ ๋น์ด ๋ถ๊ฐ๋ฅ
๊ฐ์ฒด์ ์์ฑ์ด ๋ณ๊ฒฝ๊ฐ๋ฅํ ์ด์
์ค์ ๊ฐ์ฒด๊ฐ ๋ณ๊ฒฝ์ด ๋์ง๋ง ( {} -> name: "yong") ๊ฐ์ฒด์ ๋ณ์(exam)์ฌ์ด์ ๋ฐ์ธ๋ฉ์ ๋ณ๊ฒฝ์ด ๋์ง ์๊ธฐ ๋๋ฌธ์ ๊ฐ์ฒด์ ์์ฑ์ ๋ณ๊ฒฝ ๊ฐ๋ฅ
๊ทธ๋ฌ๋ฏ๋ก ์ฌํ ๋น์ ๋ถ๊ฐ๋ฅํ์ง๋ง ๊ฐ์ฒด ์์ฑ์ ๋ณ๊ฒฝํจ์ ๋ฐ๋ผ ๋ณ์์ ๋ฐ์ธ๋ฉ๋ ๊ฐ์ฒด์ ๋ด์ฉ๊น์ง ๋ณ๊ฒฝ์ด ๋๊ธฐ ๋๋ฌธ์ ๋ถ๋ณ๊ฐ์ฒด๋ผ๊ณ ๋ถ๋ฅด๊ธฐ๋ ํ๋ค๋ค.
๐ฅ Object.freeze()
๊ธฐ๋ณธ์ ๊ณต ๋ฉ์๋์ด๋ฉฐ "๊ฐ์ฒด๋ฅผ ๋๊ฒฐํ๊ธฐ ์ํ ๋ฉ์๋"์ด๋ค
let food = {
name : "kimchi"
}
Object.freeze(food);
์ด๋ฐ์์ผ๋ก ์ฌ์ฉ์ด ๊ฐ๋ฅํ๋ฉฐ food ๋ณ์์ key value๋ฅผ ๊ฐ์ง ๊ฐ์ฒด๋ฅผ ๋ฐ์ธ๋ฉ ํ ํ ๋ฐ์ freeze๋ฅผ ๋ฉ์๋๋ฅผ ํตํด ๋ฐ์ธ๋ฉ๋ ๋ณ์๋ฅผ ๋๊ฒฐ ๊ฐ์ฒด๋ก ๋ง๋ ์ํฉ์ด๋ค. ๊ทธ๋ฌ๋ฏ๋ก food์ ๊ฐ์ฒด์ ์์ฑ์ ๋ณ๊ฒฝํ๋ ์๋๋ ๋ถ๊ฐ๋ฅํ๋ค.
food.name = 'kimchi';
console.log(food)// {name: 'kimchi'}
์ด๋ ๊ฒ ๊ฐ์ฒด ์์ฑ ์์ฒด๋ฅผ ๋ณ๊ฒฝํ๋ ์๋๋ ๋ฌด์๊ฐ ๋๋ ํ์์ด ์ผ์ด๋๋ค.
But! ๋๊ฒฐ๋ ๊ฐ์ฒด๋ฅผ ๋ฐํํ๊ธฐ๋ ํ์ง๋ง ๊ฐ์ฒด์ ์ฌํ ๋น์ ๊ฐ๋ฅํ๋ค
food = {
price : 2000
};
console.log(food);
์ด๋ ๊ฒ ๊ฐ์ฒด์ ์ฌํ ๋น์ ๊ฐ๋ฅํ์ง๋ง ์ด๊ฒ๋ ์๋ฒฝํ ๋๊ฒฐ๋ ๊ฐ์ฒด๋ผ๊ณ ๋ณด๊ธฐ๋ ํ๋ค๋ค.
๊ทธ๋ ๋ค๋ฉด ๊ฒฐ๊ตญ ๋ถ๋ณ๊ฐ์ฒด๋
const์ Object.freeze() ์กฐํฉ์ผ๋ก ๋ง๋ค์์๋ค.
const food = {
name : 'kimchi'
};
Object.freeze(food)
์ด๋ ๊ฒ ๋ฐ์ธ๋ฉ ๋ ๋ณ์๋ฅผ ์์ํ ์ํค๊ณ Object.freeze()๋ก ํด๋น ๋ณ์๋ฅผ ๋๊ฒฐ ๊ฐ์ฒด๋ฅผ ๋ง๋ค๋ฉด ๊ฐ์ฒด์ ์ฌํ ๋น๊ณผ ๊ฐ์ฒด์ ์์ฑ ๋๋ค ๋ณ๊ฒฝ๋ถ๊ฐ๋ฅํ ๋ถ๋ณ ๊ฐ์ฒด๋ฅผ ๋ง๋ค ์ ์๋ค.
๐ ์์ ๋ณต์ฌ์ ๊น์ ๋ณต์ฌ
๐ญ ์์ ๋ณต์ฌ(Shallow Copy)๋ ๊ฐ์ฒด์ ์ฐธ์กฐ๊ฐ(์ฃผ์ ๊ฐ)์ ๋ณต์ฌํ๋ ๊ฒ์ด๊ณ ๊น์ ๋ณต์ฌ(Deep Copy)๋ ๊ฐ์ฒด์ ์ค์ ๊ฐ์ ๋ณต์ฌํ๋ ๊ฒ์ ๋๋ค. ์ฐ์ ์๋ฐ์คํฌ๋ฆฝํธ์๋ ์์๊ฐ, ์ฐธ์กฐ๊ฐ ์ด ๋๊ฐ์ง ๋ฐ์ดํฐ ํ์ ์ ๊ฐ์ด ์กด์ฌํฉ๋๋ค.
๐ฅ ์์๊ฐ
ํด๋น ๊ฐ์ ๊ธฐ๋ณธ ์๋ฃํ(๋จ์ ๋ฐ์ดํฐ)๋ฅผ ์๋ฏธํฉ๋๋ค. Number, String, Boolean, null, undefined, ๋ฑ์ด ์ด ๋ฐ์ดํฐ์ ํด๋นํฉ๋๋ค. ๋ณ์์ ์์๊ฐ์ ์ ์ฅํ ์ ๋ณ์์ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์ ์ค์ ๋ฐ์ดํฐ ๊ฐ์ ์ ์ฅํ๊ฒ ๋ฉ๋๋ค. ํ ๋น๋ ๋ณ์๋ฅผ ์กฐ์ ์ ์ ์ฅ๋ ์ค์ ๊ฐ์ด ์กฐ์๋ฉ๋๋ค.
๐ฅ ์ฐธ์กฐ๊ฐ
ํด๋น ๊ฐ์ ์ฌ๋ฌ ์๋ฃํ์ผ๋ก ๊ตฌ์ฑ๋๋ ๋ฉ๋ชจ๋ฆฌ์ ์ ์ฅ๋ ๊ฐ์ฒด๋ฅผ ์๋ฏธํฉ๋๋ค. Object, symbol, array๋ฑ์ด ์ด ๋ฐ์ดํฐ์ ํด๋นํฉ๋๋ค. ๋ณ์์ ๊ฐ์ฒด๋ฅผ ์ ์ฅํ ์ ๋ ๋ฆฝ์ ์ธ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์ ๊ฐ์ ์ ์ฅํ๊ฒ ๋๊ณ ๋ณ์์ ์ ์ฅ๋ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์ ์ฐธ์กฐ(์ฆ ์์น ๊ฐ)๋ฅผ ์ ์ฅํ๊ฒ ๋ฉ๋๋ค. ๊ทธ๋์ ํ ๋น๋ ๋ณ์๋ฅผ ์กฐ์ํ ๋ ์ฌ์ค ๊ฐ์ฒด ์์ฒด๋ฅผ ์กฐ์ํ๋ ๊ฒ์ด ์๋ ํด๋น ๊ฐ์ฒด์ ์ฐธ์กฐ(์์น ๊ฐ)๋ฅผ ์กฐ์ํ๊ฒ ๋๋ ๊ฒ์ ๋๋ค.
์์๊ฐ์ ๋ณต์ฌํ ๋ ๊ทธ ๊ฐ์ด ๋ค๋ฅธ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์ ํ ๋น๋๊ธฐ ๋๋ฌธ์ ๋ณต์ฌ๋ฅผ ํ๊ณ ๊ฐ์ ์์ ํด๋ ๊ธฐ์กด์ ์์๊ฐ์ ์ ์ฅํ ๋ณ์์๋ ์ํฅ์ ์ฃผ์ง ์์ต๋๋ค. ์ด๋ ๋ฏ์ด ์ค์ ๊ฐ์ ๋ณต์ฌํ๋ ๊ฒ์ ๊น์ ๋ณต์ฌ๋ผ๊ณ ํฉ๋๋ค
ex)
const a = 7;
let b = a;
b = 1
console.log(a); //7
console.log(b); //1
์ฐธ์กฐ๊ฐ์ ๋ณต์ฌํ ๋๋ ๋ณ์๊ฐ ๊ฐ์ฒด์ ์ฐธ์กฐ๋ฅผ ๊ฐ๋ฆฌํค๊ณ ์์ด์ ๋ณต์ฌ๋ ๋ณ์ ๋ํ ๊ฐ์ฒด๊ฐ ์ ์ฅ๋ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์ ์ฐธ์กฐ๋ฅผ ํฅํด ๊ฐ๋ฆฌํค๊ณ ์์ต๋๋ค. ๊ทธ๋ ๊ธฐ ๋๋ฌธ์ ๋ณต์ฌ ๋ฐ ๊ฐ์ฒด๋ฅผ ์์ ์ ๋ ๋ณ์๋ ๋๊ฐ์ ์ฐธ์กฐ๋ฅผ ๊ฐ๋ฆฌํค๊ณ ์๊ธฐ์ ๊ธฐ์กด ๊ฐ์ฒด๋ฅผ ์ ์ฅํ ๋ณ์์ ์ํฅ์ ์ค๋๋ค. ์ด์ฒ๋ผ ๊ฐ์ฒด์ ์ฐธ์กฐ๊ฐ(์์น ๊ฐ)์ ๋ณต์ฌํ๋ ๊ฒ์ ์์ ๋ณต์ฌ๋ผ๊ณ ํฉ๋๋ค.
const a = {
number : 1
}
let b = a;
b.number = 5
console.log(a); // {number : 5}
console.log(b); // {number : 5}
์์ ๋ณต์ฌ ๋ฐฉ๋ฒ
"์์ ๋ณต์ฌ๋ ๊ฐ์ฒด๋ฅผ ๋ณต์ฌํ ๋ ๊ธฐ์กด ๊ฐ๊ณผ ๋ณต์ฌ๋ ๊ฐ์ด ๊ฐ์ ์ฐธ์กฐ๋ฅผ ๊ฐ๋ฆฌํค๊ณ ์๋ ๊ฒ์ ๋งํฉ๋๋ค. ๊ฐ์ฒด ์์ ๊ฐ์ฒด๊ฐ ์์ ๊ฒฝ์ฐ ํ ๊ฐ์ ๊ฐ์ฒด๋ผ๋ ๊ธฐ์กด ๋ณ์์ ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ๊ณ ์๋ค๋ฉด ์ด๋ฅผ ์์ ๋ณต์ฌ๋ผ๊ณ ํฉ๋๋ค"
๐ฅ Array.prototype.slice()
ํด๋น ๋ฐฉ๋ฒ์ start๋ถํฐ end ์ธ๋ฑ์ค๊น์ง ๊ธฐ์กด ๋ฐฐ์ด์์ ์ถ์ถ์ ํ๊ณ ์๋ก์ด ๋ฐฐ์ด์ ๋ฆฌํดํ๋ ๋ฉ์๋. start๋ถํฐ end ์ธ๋ฑ์ค๋ฅผ ์ค์ ์ํ ์ ๊ธฐ์กด๋ฐฐ์ด์ ์ ์ฒด ์์ ๋ณต์ฌํฉ๋๋ค.
const origin = ['a', 2, true, 4, "hi"];
const copy = origin.slice();
console.log(JSON.stringify(origin) === JSON.stringify(copy)); // true
copy.push(10);
console.log(JSON.stringify(origin) === JSON.stringify(copy)); // false
console.log(origin); // ['a', 2, true, 4, "hi"];
console.log(copy); // ['a', 2, true, 4, "hi", 10];
์ฌ๊ธฐ์์๋ array์ type์ด๋ผ ๊ธฐ์กด๋ฐฐ์ด์ ์ํฅ์ ๋ฏธ์น์ง ์๊ธฐ ๋๋ฌธ์ ๊น์ ๋ณต์ฌ๋ก ๋ณด์ผ์๋ ์์ง๋ง ์์๊ฐ์ ๊ธฐ๋ณธ์ ์ผ๋ก ๊น์ ๋ณต์ฌ์ ๋๋ค. ํ์ง๋ง array๋ ์์๊ฐ์ ์ ์ฅํ 1์ฐจ์ ๋ฐฐ์ด์ผ ๋ฟ์ด๊ธฐ ๋๋ฌธ์ ๊น์ ๋ณต์ฌ๊ฐ ์๋๋ค.
const original = [
[1, 1, 1, 1],
[0, 0, 0, 0],
[2, 2, 2, 2],
[3, 3, 3, 3],
];
const copy = original.slice();
console.log(JSON.stringify(original) === JSON.stringify(copy)); // true
// ๋ณต์ฌ๋ ๋ฐฐ์ด์๋ง ๋ณ๊ฒฝ๊ณผ ์ถ๊ฐ.
copy[0][0] = 99;
copy[2].push(98);
console.log(JSON.stringify(original) === JSON.stringify(copy)); // true
console.log(original);
// [ [ 99, 1, 1, 1 ], [ 0, 0, 0, 0 ], [ 2, 2, 2, 2, 98 ], [ 3, 3, 3, 3 ] ]
console.log(copy);
// [ [ 99, 1, 1, 1 ], [ 0, 0, 0, 0 ], [ 2, 2, 2, 2, 98 ], [ 3, 3, 3, 3 ] ]
์ด๋ ๊ฒ 1์ฐจ์ ๋ฐฐ์ด์ด ์๋๋ผ ์ค์ฒฉ๊ตฌ์กฐ๋ฅผ ๊ฐ์ง 2์ฐจ์๋ฐฐ์ด์๋ ์์ ๋ณต์ฌ๋ฅผ ์ํํ๋ ๊ฒ์ด ๋ฐ๋ก ๋ณด์ ๋๋ค.
๐ฅ Object.assign()
์ด ๋ฉ์๋๋ Object.assign(์์ฑํ ๊ฐ์ฒด, ๋ณต์ฌํ ๊ฐ์ฒด)
์ฆ ์ฒ์์๋ ์ฒซ๋ฒ์งธ ์ธ์์ ๋น ๊ฐ์ฒด๋ฅผ ๋ฃ์ด์ฃผ๊ณ ๋๋ฒ์งธ ์ธ์๋ก ๋ณต์ฌํ ๊ฐ์ฒด๋ฅผ ๋ฃ์ด์ฃผ๋ฉด ๋ฉ๋๋ค.
const object = {
a: "a",
number: {
one: 1,
two: 2,
},
};
const copy = Object.assign({}, object);
copy.number.one = 3;
console.log(object === copy); // false
console.log(object.number.one === copy.number.one); // true
Object.assign()์ ์์ฑ์ ๊ฐ์ ๋ณต์ฌํ๊ธฐ ๋๋ฌธ์ ๋ค๋ฅธ ๋์์ ์ฌ์ฉํด์ผ ํฉ๋๋ค. ์ถ์ฒ ๊ฐ์ด ๊ฐ์ฒด์ ๋ํ ์ฐธ์กฐ์ธ ๊ฒฝ์ฐ, ์ฐธ์กฐ ๊ฐ๋ง์ ๋ณต์ฌํฉ๋๋ค.
๐ฅ Spread์ฐ์ฐ์ (์ ๊ฐ์ฐ์ฐ์)
const object = {
a: "a",
number: {
one: 1,
two: 2,
},
};
const copy = {...object}
copy.number.one = 3;
console.log(object === copy); // false
console.log(object.number.one === copy.number.one); // true
๊น์ ๋ณต์ฌ ๋ฐฉ๋ฒ
"๊น์ ๋ณต์ฌ๋ ๊ฐ์ฒด๋ ๊ฐ์ฒด ์์ ๊ฐ์ฒด๊ฐ ์์ ๊ฒฝ์ฐ์๋ ์๋ณธ๊ณผ์ ์ฐธ์กฐ๊ฐ ์์ ํ ๋์ด์ง ๊ฐ์ฒด๋ฅผ ๋งํฉ๋๋ค."
๋ณต์ฌ๋ฅผ ํ๋ ๋ชฉ์ ์์ฒด๋ ๊ธฐ์กด ๊ฐ์ฒด์ ๋ณต์ฌ๋ณธ์ผ๋ก ๊ฐ์ ธ์ ๋ณ๋๋ก ํ์ฉํ๊ธฐ ์ํจ์ด ๋๋ถ๋ถ์ธ๋ฐ ๊ธฐ์กด ๊ฐ์ฒด๊น์ง ๊ฑด๋๋ฆฐ๋ค๋ฉด ์ด๊ฒ์ ๋ณต์ฌ๋ฅผ ํ๋ ๋ชฉ์ ์ ๋ฒ์ด๋๊ธฐ์ ๊น์๋ณต์ฌ๊ฐ ์ค์ํฉ๋๋ค.
๐ฅ JSON.parse && JSON.stringify
JSON.stringify()๋ ๊ฐ์ฒด๋ฅผ json ๋ฌธ์์ด๋ก ๋ณํํ๊ณ ์ด ๊ณผ์ ์์ ์๋ณธ ๊ฐ์ฒด์์ ์ฐธ์กฐ๊ฐ ๋ชจ๋ ๋์ด์ง๋ ํํ๊ฐ ์๊น๋๋ค. ๊ฐ์ฒด๋ฅผ json ๋ฌธ์์ด๋ก ๋ณํ ํ JSON.parse()๋ฅผ ์ด์ฉํด ๋ค์ ์๋์ ๊ฐ์ฒด ์ฆ ์๋ฐ์คํฌ๋ฆฝํธ ๊ฐ์ฒด๋ก ๋ง๋ค์ด์ค๋๋ค.
์ด ๋ฐฉ๋ฒ์ ๊ฐ๋จํ์ง๋ง ๋ค๋ฅธ ๋ฐฉ๋ฒ์ ๋นํด ๋๋ฆฌ๋ค๋ ๋จ์ ๊ณผ ๊ฐ์ฒด๊ฐ function์ผ ๊ฒฝ์ฐ undefined๋ก ์ฒ๋ฆฌ๊ฐ ๋ฉ๋๋ค.
const object = {
a: "a",
number: {
one: 1,
two: 2,
},
arr: [1, 2, [3, 4]],
};
const copy = JSON.parse(JSON.stringify(object));
copy.number.one = 3;
copy.arr[2].push(5);
console.log(object === copy); // false
console.log(object.number.one === copy.number.one); // false
console.log(object.arr === copy.arr); // false
console.log(object); // { a: 'a', number: { one: 1, two: 2 }, arr: [ 1, 2, [ 3, 4 ] ] }
console.log(copy); // { a: 'a', number: { one: 3, two: 2 }, arr: [ 1, 2, [ 3, 4, 5 ] ] }
๐ฅ ์ฌ๊ทํจ์๋ฅผ ์ด์ฉํ ๋ณต์ฌ
ํ์ง๋ง ๋ณต์กํ๊ณ ์ดํดํ๊ธฐ ์ด๋ ต์ต๋๋ค.
const object = {
a: "a",
number: {
one: 1,
two: 2,
},
arr: [1, 2, [3, 4]],
};
function deepCopy(object) {
if (object === null || typeof object !== "object") {
return object;
} // ๊ฐ์ฒด์ธ์ง ๋ฐฐ์ด์ธ์ง ํ๋จ
const copy = Array.isArray(object) ? [] : {};
for (let key of Object.keys(object)) {
copy[key] = deepCopy(object[key]);
}
return copy;
}
const copy = deepCopy(object);
copy.number.one = 3;
copy.arr[2].push(5);
console.log(object === copy); // false
console.log(object.number.one === copy.number.one); // false
console.log(object.arr === copy.arr); // false
console.log(object); // { a: 'a', number: { one: 1, two: 2 }, arr: [ 1, 2, [ 3, 4 ] ] }
console.log(copy); // { a: 'a', number: { one: 3, two: 2 }, arr: [ 1, 2, [ 3, 4, 5 ] ] }
๐ฅ Lodash ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ด์ฉ
const deepCopy = require("lodash.clonedeep")
const object = {
a: "a",
number: {
one: 1,
two: 2,
},
arr: [1, 2, [3, 4]],
};
const copy = deepCopy(object);
copy.number.one = 3;
copy.arr[2].push(5);
console.log(object === copy); // false
console.log(object.number.one === copy.number.one); // false
console.log(object.arr === copy.arr); // false
console.log(object); // { a: 'a', number: { one: 1, two: 2 }, arr: [ 1, 2, [ 3, 4 ] ] }
console.log(copy); // { a: 'a', number: { one: 3, two: 2 }, arr: [ 1, 2, [ 3, 4, 5 ] ] }
๋ง์ง๋ง์ผ๋ก Lodash ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ด ์์ต๋๋ค. ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ด์ฉํ์ฌ ์์ ํ๊ณ ์ฝ๊ฒ ๊น์ ๋ณต์ฌ๋ฅผ ํ๋ ์ฅ์ ์ด ์๋๋ฐ ์ค์น๋ฅผ ํด์ผํ๋ค๋ ๋ฌธ์ ์ ๊ฐ๋ฐ์๋ ํจ์จ์ ์ด์ง๋ง ์ฝ๋ฉํ ์คํธ ๋ฑ์๋ module์ฒ๋ผ ์ฌ์ฉํ ์ ์๋ค๋ ๊ฒ์ด ํฐ ๋จ์ ์ ๋๋ค.
๐ ํธ์ด์คํ ๊ณผ TDZ๋ ๋ฌด์์ธ๊ฐ?
๐์ค์ฝํ, ํธ์ด์คํ , TDZ
๐ฅ ์ค์ฝํ
๋ณ์๋ ํจ์์ ์ ๊ทผํ ์ ์๋ ์์น
function foo() {
var x;
}
์ฌ๊ธฐ์์ x์ ์ค์ฝํ๋ foo() ์ ๋๋ค.
๐ญ ์ดํ์ ์ค์ฝํ
์ ์ ์ค์ฝํ(Static scope), ๋ ์์ปฌ ์ค์ฝํ(Lexical scope)๋ผ๊ณ ๋ ๋ถ๋ฆฌ๋ฉฐ, ํ๋ก๊ทธ๋จ์ ์คํํ์ง ์๊ณ ์์ค ์ฝ๋์ ์กด์ฌํ๋๋๋ก ํด์ํ ์ค์ฝํ์ ๋๋ค.
๐ญ ๋ณ์ ์ค์ฝํ
์ดํ์ (์ ์ )์ผ๋ก ์ง์ ๋๋ฉฐ, ์ฆ ํ๋ก๊ทธ๋จ์ ์ ์ ๊ตฌ์กฐ๋ฅผ ๋ณด๋ฉด ๋ณ์์ ์ค์ฝํ๋ฅผ ํ๋จํ ์ ์๊ณ ํจ์๋ฅผ ์ด๋์ ํธ์ถํ๋์ง ๋ฑ์ ์ํฅ์ ๋ฐ์ง ์๋๋ค. ๋ํ ๋ณ์ ์ค์ฝํ๋ ํจ์์ด๋ฉฐ, ํจ์๋ง์ด ์ ์ค์ฝํ๋ฅผ ๋์ ํ ์ ์์ต๋๋ค.
๐ญ ์ค์ฒฉ ์ค์ฝํ
์ค์ฝํ๊ฐ ๋ณ์์ ์ค์ฝํ ์์ ์ค์ฒฉ๋์ด ์์ผ๋ฉด ๊ทธ ๋ณ์๋ ํด๋น ์ค์ฝํ ์ ์ฒด์์ ์ ๊ทผํ ์ ์์ต๋๋ค.
function foo(arg){
function bar(){ //์ค์ฒฉ ์ค์ฝํ bar()
console.log(`Hi, ${arg}`);
}
bar();
}
foo("jacob"); //Hi, jacob
๐ญ Shadowing
๋ด๋ถ ์ค์ฝํ์์ ์ธ๋ถ ์ค์ฝํ์ ์๋ ๋ณ์์ ์ด๋ฆ์ด ๊ฐ์ ๋ณ์๋ฅผ ์ ์ธํ๋ฉด, ๋ด๋ถ ์ค์ฝํ์ ๊ทธ ์์ ์ค์ฒฉ๋ ๋ชจ๋ ์ค์ฝํ๋ ์ธ๋ถ ์ค์ฝํ์ ์ด๋ฆ์ด ๊ฐ์ ๋ณ์์ ์ ๊ทผํ ์ ์์ต๋๋ค. ๋ด๋ถ ๋ณ์๊ฐ ๋ฐ๋์ด๋ ์ธ๋ถ ๋ณ์๋ ๋ฐ๋์ง ์์ผ๋ฉฐ, ๋ด๋ถ ์ค์ฝํ์์ ๋น ์ ธ๋๊ฐ๋ฉด ๋ค์ ์ ๊ทผํ ์ ์์ต๋๋ค.
var x = "global";
function f(){
var x = "local";
console.log(x); // local
}
f(); // local
console.log(x); // global
๐ฅ ํธ์ด์คํ
ํจ์ ์์ ์๋ ์ ์ธ๋ค์ ๋ชจ๋ ๋์ด ์ฌ๋ ค์ ํด๋น ํจ์ ์ ํจ ์ค์ฝํ์ ์ต์๋จ์ ์ ์ธ ํ๋ ๊ฒ.
(var ์ ์ธ๋ฌธ์ด๋ function ์ ์ธ๋ฌธ ๋ฑ์ ํด๋น ์ค์ฝํ์ ์ ๋๋ก ์ฎ๊ธด ๊ฒ์ฒ๋ผ ๋์ํ๋ ํน์ฑ)
ํธ์ด์คํ ํด์ผํ ๋์
var ๋ณ์ ์ ์ธ๊ณผ ํจ์์ ์ธ๋ฌธ์์๋ง ํธ์ด์คํ
์ด ์ผ์ด๋ฉ๋๋ค.
var ๋ณ์/ํจ์์ ์ ์ธ๋ง ์๋ก ๋์ด ์ฌ๋ ค์ง๋ฉฐ, ํ ๋น์ ๋์ด ์ฌ๋ ค์ง์ง ์์ต๋๋ค.
let/const ๋ณ์ ์ ์ธ๊ณผ ํจ์ํํ์์์๋ ํธ์ด์คํ
์ด ๋ฐ์ x
๐ฅ var , let , const ํค์๋๋ก ์ ์ธ๋ ๋ณ์๋ ์ ์ธ ๋ถ๋ถ๋ง ๋์ด์ฌ๋ ค์ง๋ค๊ณ ์๊ฐํ ์ ์์ต๋๋ค. ๋ฐ๋ผ์ var ์ ๊ฒฝ์ฐ์๋ ๋ณ์ ์ ์ธ์ ์๋ ์ฐธ์กฐํ ์ ์์ง๋ง ํ ๋น์ ํ์ง ์์๊ธฐ์ undefined์ ๋๋ค.
let ๋๋ const๊ฐ ํธ์ด์คํ ์ด ๋ฐ์ํ์ง ์๋ ์ด์
๐ฅ ์๋ณ์๊ฐ ํธ์ด์คํ ํ ์ค์ ์ฝ๋์์ ์ ์ธ๋๊ธฐ ์ ๊น์ง TDZ(Temporal Dead Zone/์ผ์์ ์ฌ๊ฐ์ง๋)์ ์๊ธฐ ๋๋ฌธ์ let, const ์ ์ธ์ฝ๋๊ฐ ์๋ ๊ณณ ์ด์ ์๋ ํด๋น ๋ณ์์ ์ฐธ์กฐํ ์ ์๊ฒ ๋ฉ๋๋ค.
๐ฅ Temporal Dead Zone(TDZ)
์ฐธ์กฐ ์ค๋ฅ๊ฐ ๋๋ ๊ตฌ๊ฐ์ธ ์ค์ฝํ ์์์ง์ ๋ถํฐ ์ด๊ธฐํ ์ง์ ๊น์ง์ ๊ตฌ๊ฐ.
์ด๊ธฐํ๊ฐ ๋๊ธฐ ์ ๊น์ง๋ TDZ๋ผ๋ ๊ณณ์ ๋จธ๋ฌผ๋ฌ์ ์ด๊ธฐํ(ํน์ ํ ๋น)์ด ๋ ๋๊น์ง ์ ์ '์ฃฝ์ด์๋ ์ํ'์ด๊ธฐ ๋๋ฌธ์ ์ ์ธ ์ ์ ์ฐธ์กฐ๊ฐ ๋ถ๊ฐ๋ฅํ ๊ฒ. ์ ์ธ ์ ์ ๋ณ์๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ๋นํ์ฉํ๋ ๊ฐ๋
์์ ๊ณต๊ฐ์
๋๋ค.
console.log(a); // undefined
f1(); // undefined
console.log(f2) // undefined
f2(); // TypeError: f2 is not a function
function f1(){
console.log(b);
var b = 5;
}
var f2 = function () {
console.log(c);
var c = 7;
}
var a = 10;
์ง์ญ๋ณ์ : {}์์์ ์ ์ธ๋ ๋ณ์ ์ฆ ๋ธ๋ก ์์์๋ง ์ฌ์ฉ๊ฐ๋ฅ
์ ์ญ๋ณ์ : {}๋ฐ์์ ์ ์ธ๋ ๋ณ์ ์ฆ ์ด๋๋ ์ง ์ฐ์ผ์ ์๋ ๋ณ์
ํธ์ด์คํ ์ function ์์์ ์ด ๊ฒ ๋นผ๊ณ ๋ ์ ๋ถ ์ ์ญ๋ณ์๋ผ๊ณ ์๊ฐํ๋ฉด ๋ฉ๋๋ค.
๐ฅ const , let ๋ง๊ณ ๋ class ๊ตฌ๋ฌธ๊ณผ ํด๋์ค์ constructor() ๋ด๋ถ์ super(), ๊ธฐ๋ณธ ํจ์ ๋งค๊ฐ๋ณ์๋ TDZ ์ ํ์ด ์์ต๋๋ค. ๋ฐ๋ฉด var , function ๊ตฌ๋ฌธ์ TDZ์ ์ํฅ์ ๋ฐ์ง ์์ผ๋ฉฐ ํ์ฌ ์ค์ฝํ์์ ํธ์ด์คํ ์ด ๋ฉ๋๋ค.
๐ํจ์ ์ ์ธ๋ฌธ๊ณผ ํจ์ ํํ์์์ ํธ์ด์คํ ๋ฐฉ์์ ์ฐจ์ด
๐ฅ ํจ์ ์ ์ธ์(function declaration)
ํจ์๋ช ์ด ์ ์๋์ด ์๊ณ ๋ณ๋์ ํ ๋น ๋ช ๋ น์ด ์๋ ๊ฒ
function sum(a,b) {
return a + b;
}
๐ฅ ํจ์ ํํ์(function expression)
์ ์ํ function์ ๋ณ๋์ ๋ณ์์ ํ ๋นํ๋ ๊ฒ
const sum = function(a,b) {
return a +b;
}
์ฃผ์ ์ฐจ์ด์ ์ด ํธ์ด์คํ ์์ ๋ฐ์ํ๊ฒ๋๋๋ฐ
๐ฅ ํจ์ ์ ์ธ์์ ํจ์ ์ ์ฒด๋ฅผ ํธ์ด์คํ ํฉ๋๋ค. ์ ์๋ ๋ฒ์์ ๋งจ ์๋ก ํธ์ด์คํ ๋์ ํจ์ ์ ์ธ ์ ์ ํจ์๋ฅผ ์ฌ์ฉํ ์ ์๋ค๋ ๊ฒ์ ๋๋ค.
๐ฅ ํจ์ ํํ์์ ๋ณ๋์ ๋ณ์์ ํ ๋นํ๊ฒ ๋๋๋ฐ, ๋ณ์๋ ์ ์ธ๋ถ์ ํ ๋น๋ถ๋ฅผ ๋๋์ด ํธ์ด์คํ ํ๊ฒ ๋ฉ๋๋ค. ์ ์ธ๋ถ๋ง ํธ์ด์คํ ํ๊ฒ ๋ฉ๋๋ค.
sum(50, 50); // 100
minus(100, 50) // Uncaught TypeError: minus is not a function
function sum(a, b) { // ํจ์ ์ ์ธ์
return a + b;
}
var minus = function (a,b) { // ํจ์ ํํ์
return a - b;
}
๐ฅ ํจ์ ์ ์ธ์ => ์ ์์ ์ผ๋ก ํด๋น ๊ฐ์ ์ถ๋ ฅ
ํธ์ด์คํ ์ ๋ง์น๊ฒ ๋๋ค๋ฉด
function sum(a, b) { // ํจ์ ์ ์ธ์ - ํจ์ ์ ์ฒด ํธ์ด์คํ
return a + b;
};
var minus; // ํจ์ํํ์ - ์ ์ธ๋ถ๋ง ํธ์ด์คํ
sum(50, 50); // 100
minus(100, 50) // Uncaught TypeError: minus is not a function
function (a,b) { // ํจ์ ํํ์ - ํ ๋น๋ถ๋ ๊ทธ๋๋ก
return a - b;
}
์๋์ ๊ฐ์ด, ์ค๋ฅ๋๋ ๋ถ๋ถ, ์ฆ ํจ์ ํํ์์ ์ฝ๋๋ฅผ ํธ์ถํ๋ ๋ถ๋ถ ์์ ์์ฑํ๋ฉด ์๋ฌ์์ด ์ ์์ ์ผ๋ก ์ถ๋ ฅ๋ฉ๋๋ค.
var minus = function (a,b) { // ํจ์ ํํ์
return a - b;
}
sum(50, 50); // 100
minus(100, 50) // 50
function sum(a, b) { // ํจ์ ์ ์ธ์
return a + b;
};
๐ฅ ํจ์ ์ ์ธ์์ผ๋ก ์์ฑํ ํจ์๋ ํจ์ ์ ์ฒด๊ฐ ํธ์ด์คํ ์ด ๋๋๋ฐ ์ ์ญ์ ์ผ๋ก ์ ์ธํ๊ฒ ๋ ์ ์ค๋ณต์ ์ผ๋ก ๋๋ช ์ ํจ์๋ฅผ ์ฐ๊ฒ ๋๋ค๋ฉด ์๋ฌ๋ฅผ ๋ฐ์ ์ํฌ ์ ์์ต๋๋ค. ํจ์ ํํ์์ผ๋ก ์์ฑํ๊ฒ ๋ ์ ์ด๋ฅผ ๋ฏธ์ฐ์ ๋ฐฉ์ง ํ ์ ์์ต๋๋ค.
๐let, const, var, function ์ ์คํ์๋ฆฌ
๐ญ let๋ณ์์ const ๋ณ์๋ ES6 ์ดํ ์คํ์์ ์๋กญ๊ฒ ๋ฑ์ฅํ ๋ณ์์ ๋๋ค. ์ด์ ๊ฐ์ ์ด์ ๋๋ฌธ์ ๋ธ๋ผ์ฐ์ ๋ฐฐํฌ์ฉ ์ฝ๋ ๊ฐ์ ๊ฒฝ์ฐ๋ ์์ง๋ var ๋ณ์๋ง ์ฌ์ฉ๋๋ ๊ฒฝ์ฐ๋ ์์ต๋๋ค.
์ฐ์ var, let, const 3๊ฐ์ง๋ฅผ ๊ตฌ๋ถ ์ง๋ ๊ฐ์ฅ ํฐ ์ฐจ์ด์ ์
1. ๊ฐ ๋ณ๊ฒฝ ์ฌ๋ถ
2. ์ค์ฝํ ๋ฒ์
3. ํธ์ด์คํ ๊ฐ๋ฅ ์ฌ๋ถ
์ด๋ฉฐ ์ฐ์ ์์์ ์์ด์๋ const, let, var ์์ ๋๋ค.
๐ฅ ๊ฐ ๋ณ๊ฒฝ ์ฌ๋ถ
var์ let์ ๊ฐ์ด ์ ์ธ๋ ์ดํ์๋ ๊ฐ์ ๋ณ๊ฒฝํ ์ ์์ง๋ง, const๋ ์์ฑํ ๋ ์ ์ธ๋ ์ด๊ธฐ๊ฐ์ ๋ณ๊ฒฝํ ์ ์์ต๋๋ค.
๐ฅ ์ค์ฝํ ๋ฒ์
var์ ํจ์์ค์ฝํ๋ฅผ ๊ฐ์ง์ง๋ง, let๊ณผ const ๋ณ์๋ ๋ธ๋ก ์ค์ฝํ๋ฅผ ๊ฐ์ง๊ฒ ๋ฉ๋๋ค.
๐ฅ ํธ์ด์คํ ๊ฐ๋ฅ ์ฌ๋ถ
var๋ ํธ์ด์คํ ์ด ๊ฐ๋ฅํ์ง๋ง, let๊ณผ const๋ ํธ์ด์คํ ์ด ๋ถ๊ฐ๋ฅํฉ๋๋ค.
๐ญ function()์ ์๋ฆฌ
๐ฅํจ์๋ฅผ ์คํํ๊ธฐ ์ํด์๋ ์ด๋ฆ(์๋ณ์)์ด ํ์ํฉ๋๋ค. ์ด๋ฆ์ด ์์ด์ผ ์ค์ฝํ์์ ๊ฐ์ ์ฐธ์กฐํ ์ ์๊ธฐ ๋๋ฌธ์ ๋๋ค.
๐ฅ์์ง์ด ํจ์ ์ ์ธ๋ฌธ์ ๋ง๋๋ฉด ์๋ณ์๋ฅผ ๊ด๋ฆฌํ๋ ํน๋ณํ ์งํฉ(EnviromentRecord)์ ํจ์์ ์ด๋ฆ์ ์๋ณ์๋ก ๋ฃ๊ณ ํจ์ ๊ฐ์ฒด๋ฅผ ์์ฑํ์ฌ ์ฐธ์กฐํฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ ํจ์ ์คํ ๊ตฌ๋ฌธ ์ค foo๋ฅผ ๋ง๋๋ฉด ๊ฐ์ ์ค์ฝํ๋ฅผ ํตํด ๊ฐ์ ธ์ต๋๋ค. ๊ทธ ๋ค์ ๊ตฌ๋ฌธ์ด () ์ด๋ฏ๋ก ์คํ ๊ฐ๋ฅํ๋ค๋ฉด ์คํํฉ๋๋ค.
๐ฅ๋ง์ฝ ์ค์ฝํ์์ ์๋ณ์๋ฅผ ์ฐพ์ง ๋ชปํ๋ค๋ฉด ์ฐธ์กฐ ์๋ฌ(ReferenceError)๋ฅผ ์ถ๋ ฅํ๊ณ , ์๋ณ์๋ ์ฐพ์์ง๋ง ์คํํ ์ ์๋ ํ์ ์ด๋ผ๋ฉด ํ์ ์๋ฌ(TypeError)๋ฅผ ์ถ๋ ฅํฉ๋๋ค.
๐ ์คํ ์ปจํ ์คํธ์ ์ฝ ์คํ
๐ญ ์คํ ์ปจํ ์คํธ์ ์ฝ ์คํ
์ด ๊ณผ์ ์ ์ดํดํ ๋ ค๋ฉด ์ฐ์ ์๋ฐ์คํฌ๋ฆฝํธ ์์ง ์์ฒด๊ฐ ์ด๋ป๊ฒ ์ฝ๋๋ฅผ ์ฝ๋๊ฐ์ ๋ํด์ ๋ค์ด๊ฐ๋ด์ผ ํฉ๋๋ค. ๋ง๋ ์์ฌํํ์ ๋ด๊ฐ ์ด๋ป๊ฒ ํ๋์ ๋ฐ๋ผ ๊ฒฐ๊ณผ๊ฐ ๋ฌ๋ผ์ง๋ฏ์ด ์๋ฐ์คํฌ๋ฆฝํธ ๋ํ ์ฝ๋๋ฅผ ์ดํดํ๋ ๋๋ฆ์ ์์น์ด ์์ต๋๋ค.
๐ฅ ์คํ ์ปจํ ์คํธ(Execution Context)
์คํ ์ปจํ ์คํธ๋ ์๋ฐ์คํฌ๋ฆฝํธ์ ํต์ฌ ๊ฐ๋ ์ผ๋ก ์ฝ๋๋ฅผ ์คํํ๊ธฐ ์ํด ํ์ํ ํ๊ฒฝ์ด๋ค. ๋ ์์ธํ ๋งํ์๋ฉด, ์คํํ ์ฝ๋์ ์ ๊ณตํ ํ๊ฒฝ ์ ๋ณด๋ค์ ๋ชจ์๋์ ๊ฐ์ฒด์ ๋๋ค. ๋ชจ๋ ์ฝ๋๋ ํน์ ํ ์คํ ์ปจํ ์คํธ ์์์ ์คํ๋ฉ๋๋ค.
javascript๋ ์ด๋ค execution context๊ฐ ํ์ฑํ๋๋ ์์ ์ ์ ์ธ๋ ๋ณ์๋ค์ ์๋ก ๋์ด์ฌ๋ฆฌ๊ณ (hoisting), ์ธ๋ถ ํ๊ฒฝ ์ ๋ณด๋ฅผ ๊ตฌ์ฑํ๊ณ , this๊ฐ์ ์ค์ ํ๋ ๋ฑ์ ๋์์ ์ํํ๋๋ฐ, ์ด๋ก ์ธํด ๋ค๋ฅธ ์ธ์ด์์๋ ๋ฐ์ํ ์ ์๋ ํน์ดํ ํ์๋ค์ด ๋ฐ์
๐ฅ Global Execution Context
๋ํดํธ ์คํ ์ปจํ ์คํธ๋ก, ์๋ฐ์คํฌ๋ฆฝํธ ํ์ผ์ด ์์ง์ ์ํด ์ฒ์ ๋ก๋๋์์ ๋ ์คํ๋๊ธฐ ์์ํ๋ ํ๊ฒฝ์ด๋ค.
๐ฅ Function Execution Context
์ฐ๋ฆฌ๊ฐ execution context๋ฅผ ๋ฐ๋ก ๊ตฌ์ฑํ๋ ๋ฐฉ๋ฒ์ ํจ์๋ฅผ ์คํํ๋ ๊ฒ ๋ฟ์ด๋ค. ํจ์๊ฐ ํธ์ถ๋๊ณ ์คํ๋จ์ ๋ฐ๋ผ์ ํด๋น ํจ์ ์์์ ์์ฑ๋๋ ์ปจํ ์คํธ. ๊ฐ๊ฐ์ ํจ์๋ ๊ณ ์ ์ ์คํ ์ปจํ ์คํธ๋ฅผ ๊ฐ์ง๋ค. ๊ทธ๋ฆฌ๊ณ ์ ์ญ ์คํ ์ปจํ ์คํธ์ ์ธ์ ๋ ์ ๊ทผํ ์ ์๋ค.
(1) Global Execution Context ์์ฑ.
์๋ฐ์คํฌ๋ฆฝํธ ํ์ผ์ด ์ด๋ฆฌ๋ ์๊ฐ(๋ณ๋์ ๋ช ๋ น ์์ด) ์ ์ญ ์คํ ์ปจํ ์คํธ๊ฐ ์์ฑ๋๋ค. ๊ทธ๋ฆฌ๊ณ global execution context๊ฐ ๊ฐ์ฅ ๋จผ์ callstack์ push๋๋ค. ์ง๊ธ callstack์ ๋งจ ์์๋ global execution์ด ์์ผ๋ฏ๋ก ์๋ฐ์คํฌ๋ฆฝํธ ์์ง์ ์ด์ ์ ์ญ ์คํ ์ปจํ ์คํธ ์์์ ์ฝ๋๋ฅผ ์ฝ์ด๋ด๋ ค๊ฐ๊ธฐ ์์ํ๋ค.
(2) fooํจ์ ํธ์ถ.
fooํจ์๋ฅผ ํธ์ถํ ๋, Global Execution Context๋ ๋ฉ์ถ๋ค. ์๋ํ๋ฉด ์๋ฐ์คํฌ๋ฆฝํธ๋ ์ฑ๊ธ ์ค๋ ๋ ํ๊ฒฝ์ด๊ธฐ ๋๋ฌธ์, ํ ๋ฒ์ ํ๋์ ์ฝ๋๋ง์ ์คํํ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค.
(3) ์๋ฐ์คํฌ๋ฆฝํธ ์์ง์ fooํจ์์ ๋ํ ํ๊ฒฝ ์ ๋ณด๋ฅผ ์์งํด์ foo execution context๋ฅผ ์์ฑํ ํ, callstack์ pushํ๋ค. ์ด์ ํจ์ ๋ด๋ถ์ ์ฝ๋๋ค์ด ์์๋๋ก ์งํ๋๋ค.
(4) barํจ์ ํธ์ถ. fooํจ์์ Execution Context๋ ๋ฉ์ถ๋ค.
(5) barํจ์์ Execution Context๊ฐ ์์ฑ๋๊ณ callstack์ push๋๋ค. ์ฝ์ด๋ด๋ ค๊ฐ๋ค. console.logํจ์๋ฅผ ์คํํ๋ค. ์ ์ญ ๋ณ์์ธ a์ ๊ฐ์ด ์ฝ์์ฐฝ์ ๋ธ์ผ๋ก์จ console.logํจ์์ ์คํ์ด ๋๋๋ค.
(6) ๋ ์ฝ์ด๋ด๋ ค๊ฐ ๊ฒ ์์ผ๋ฏ๋ก barํจ์์ Execution Context๊ฐ ์ข ๋ฃ๋๋ค. callstack์์ pop-out๋๋ค. ๊ทธ๋ฆฌ๊ณ ํด๋น ํจ์ ๋ฐ๋ก ๋ฐ์ Execution Context, ์ฌ๊ธฐ์์ fooํจ์์ Execution Context๊ฐ ๊ณ์๋๋ค.
(7) ๋ ์ฝ์ด๋ด๋ ค๊ฐ ๊ฒ ์์ผ๋ฏ๋ก fooํจ์์ Execution Context๊ฐ ๋๋๋ค.
(8) ๋ ์ฝ์ด๋ด๋ ค๊ฐ ๊ฒ ์์ผ๋ฏ๋ก Global Execution Context๊ฐ ๋๋๋ค.
๐ฅ callstack(์ฝ์คํ)
call์ ํธ์ถ์ ๋ปํ๋ค.
stack์ ์ถ์
๊ตฌ๊ฐ ํ๋๋ฟ์ธ ๊น์ ์ฐ๋ฌผ ๊ฐ์ ๋ฐ์ดํฐ ๊ตฌ์กฐ๋ค.
๋ฐ๋ผ์ callstack์ ์๋ฐ์คํฌ๋ฆฝํธ๊ฐ ํจ์ ํธ์ถ์ ๊ธฐ๋กํ๊ธฐ ์ํด ์ฌ์ฉํ๋ ์ฐ๋ฌผ ํํ์ ๋ฐ์ดํฐ ๊ตฌ์กฐ์ด๋ค.
ํญ์ ๋งจ ์์ ๋์ธ ํจ์๋ฅผ ์ฐ์ ์ผ๋ก ์คํ๋๋ค. ์ด๋ฐ ์์ผ๋ก ์๋ฐ์คํฌ๋ฆฝํธ ์์ง์ ๊ฐ์ฅ ์์ ์์ฌ์๋ context์ ๊ด๋ จ ์๋ ์ฝ๋๋ค์ ์คํํ๋ ์์ผ๋ก ์ ์ฒด ์ฝ๋์ ํ๊ฒฝ๊ณผ ์์๋ฅผ ๋ณด์ฅํ๋ค.
๐ ์ค์ฝํ ์ฒด์ธ, ๋ณ์ ์๋ํ
๐ฅ ์ค์ฝํ ์ฒด์ธ
ํจ์๋ ์ ์ญ์์ ์ ์ํ ์๋ ์๊ณ ํจ์ ๋ชธ์ฒด ๋ด๋ถ์์๋ ํ ์ ์๋ค. ํจ์ ๋ชธ์ฒด ๋ด๋ถ์์ ํจ์๊ฐ ์ ์๋ ๊ฒ์ 'ํจ์์ ์ค์ฒฉ', ์ค์ฒฉ ํจ์๋ฅผ ํฌํจํ๋ ํจ์๋ฅผ '์ธ๋ถ ํจ์'๋ผ๊ณ ํ๋ค.
ํจ์๋ ์ค์ฒฉ๋ ์ ์์ผ๋ฏ๋ก ํจ์์ ์ง์ญ ์ค์ฝํ๋ ์ค์ฒฉ๋ ์ ์๋๋ฐ, ์ด๋ ์ค์ฝํ๊ฐ ํจ์์ ์ค์ฒฉ์ ์ํด ๊ณ์ธต์ ๊ตฌ์กฐ๋ฅผ ๊ฐ๋๋ค๋ ๊ฒ์ ์๋ฏธํ๋ค. ์ด๋ ์ธ๋ถ ํจ์์ ์ง์ญ ์ค์ฝํ๋ฅผ ์ค์ฒฉ ํจ์์ ์์ ์ค์ฝํ๋ผ๊ณ ์ง์นญํ๋ค.
var x = "global x";
var y = "global y";
function outer (){
var z = "outer's local z";
console.log(x); //global x
console.log(y); //global y
console.log(z); //outer's local z
function inner (){
var x = "inner's local x";
console.log(x); //inner's local x
console.log(y); //global y
console.log(z); //outer's local z
}
inner();
}
outer();
console.log(x); //global x
console.log(z); //ReferenceError: z is not defined
์์ ์์ ์ฝ๋๋ outer ํจ์๊ฐ ๋ง๋ ์ง์ญ ์ค์ฝํ ๋ด์ inner ํจ์๊ฐ ๋ง๋ ์ง์ญ ์ค์ฝํ๊ฐ ์์ผ๋ฏ๋ก outer ์ค์ฝํ๊ฐ inner ์ค์ฝํ์ ์์ ์ค์ฝํ์ด๋ค. ๊ทธ๋ฆฌ๊ณ outer ํจ์์ ์ง์ญ ์ค์ฝํ์ ์์ ์ค์ฝํ๋ ์ ์ญ ์ค์ฝํ์ด๋ค.
์ด์ฒ๋ผ ๋ชจ๋ ์ค์ฝํ๋ ํ๋์ ๊ณ์ธต์ ๊ตฌ์กฐ๋ก ์ฐ๊ฒฐ๋๋ฉฐ, ๋ชจ๋ ์ง์ญ ์ค์ฝํ์ ์ต์์ ์ค์ฝํ๋ ์ ์ญ ์ค์ฝํ์ด๋ค.
๐ฅ ์ค์ฝํ ์ฒด์ธ์ ์ํ ๋ณ์ ๊ฒ์
๋ณ์๋ฅผ ์ฐธ์กฐํ ๋ ์๋ฐ์คํฌ๋ฆฝํธ ์์ง์ ์ค์ฝํ ์ฒด์ธ์ ํตํด ๋ณ์๋ฅผ ์ฐธ์กฐํ๋ ์ฝ๋์ ์ค์ฝํ์์ ์์ํ์ฌ ์ฐธ์กฐํ ๋ณ์๊ฐ ์กด์ฌํ์ง ์๋๋ค๋ฉด ์์ ์ค์ฝํ์ ๋ฐฉํฅ์ผ๋ก ์ด๋ํ๋ฉฐ ์ ์ธ๋ ๋ณ์๋ฅผ ๊ฒ์ํ๋ค. ์ด๋ฅผ ํตํด ์์ ์ค์ฝํ์์ ์ ์ธํ ๋ณ์๋ฅผ ํ์ ์ค์ฝํ์์ ์ฐธ์กฐํ ์ ์๋ค. ๋ฐ๋๋ก ํ์ ์ค์ฝํ์์ ์ ํจํ ๋ณ์๋ ์์ ์ค์ฝํ์์ ์ฐธ์กฐํ ์ ์๋ค.
๐ฅ ๋ณ์ ์๋ํ
๐ฅ ์บก์ํ๋ ๊ฐ์ฒด์ ์ํ๋ฅผ ๋ํ๋ด๋ ํ๋กํผํฐ๋ฅผ ์ฐธ์กฐํ๊ณ ์กฐ์ํ ์ ์๋ ๋์์ธ ๋ฉ์๋๋ฅผ ํ๋๋ก ๋ฌถ๋ ๊ฒ์ ๋งํ๋ค. ์บก์ํ๋ ๊ฐ์ฒด์ ํน์ง ํ๋กํผํฐ๋ ๋ฉ์๋๋ฅผ ๊ฐ์ถ ๋ชฉ์ ์ผ๋ก ์ฌ์ฉํ๊ธฐ๋ ํ๋๋ฐ ์ด๋ฅผ ์ ๋ณด ์๋์ด๋ผ ํ๋ค.
์ ๋ณด ์๋์ ์ ์ ์น ๋ชปํ ์ ๊ทผ์ผ๋ก๋ถํฐ ๊ฐ์ฒด์ ์ํ๊ฐ ๋ณ๊ฒฝ๋๋ ๊ฒ์ ๋ฐฉ์งํด ์ ๋ณด๋ฅผ ๋ณดํธํ๋ค.
๐ฅ ๋๋ถ๋ถ์ ๊ฐ์ฒด์งํฅ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด๋ ํด๋์ค๋ฅผ ์ ์ํ๊ณ ๊ทธ ํด๋์ค๋ฅผ ๊ตฌ์ฑํ๋ ๋ฉค๋ฒ์ public, private, protected ๊ฐ์ ์ ๊ทผ ์ ํ์๋ฅผ ์ ์ธํ์ฌ ๊ณต๊ฐ ๋ฒ์๋ฅผ ํ์ ํ ์ ์๋ค. ํ์ง๋ง ์๋ฐ์คํฌ๋ฆฝํธ๋ ์ ๊ทผ ์ ํ์๋ฅผ ์ ๊ณตํ์ง ์๋๋ค.
๐ฌ ์ค์ต๊ณผ์
let b = 1;
function hi () {
const a = 1;
let b = 100;
b++;
console.log(a,b); //const, let์ ๋ธ๋ญ์ค์ฝํ์์ ์ ํจํด์ ํจ์ ๋ด๋ถ์ ๋ณ์๋ค์ ์ ๊ทผ ํ ์ถ๋ ฅ
}
console.log(a); //Reference Error ์ค๋ฅ๊ฐ ๋ฐ์
//(a๋ณ์๋ฅผ ์ ์ญ์ ์ผ๋ก ๋ง๋ค์ด์ฃผ์ง ์์์ ์ด๊ฒ์ ํด๊ฒฐํ๊ธฐ ์ํด์๋ let b = 1;์ชฝ์ let a= 1; ์ด๋ฐ์์ผ๋ก ๋ง๋ค์ด์ค์ผํจ)
console.log(b); //let b=1์ ์ ๊ทผ(์ ์ญ b๋ณ์) 1์ ์ถ๋ ฅ
hi(); //ํจ์ ์คํ => 1, 101์ ์ถ๋ ฅ
console.log(b); //let b=1์ ์ ๊ทผ(์ ์ญ b๋ณ์) 1์ ์ถ๋ ฅ