# * YOU DON'T KNOW JS - ํ์
# ํ์
์๋ฐ์คํฌ๋ฆฝํธ ๋ช
์ธ์์ ํ์
์ ์ ์ : ์๋ฐ์คํฌ๋ฆฝํธ ์์ง, ๊ฐ๋ฐ์ ๋ชจ๋์๊ฒ ์ด๋ค ๊ฐ์ ๋ค๋ฅธ ๊ฐ๊ณผ ๋ถ๋ณํ ์ ์๋, ๊ณ ์ ํ ๋ด๋ถ ํน์ฑ์ ์งํฉ์ด๋ค.
ex) ๊ธฐ๊ณ(์์ง)์ ์ฌ๋(๊ฐ๋ฐ์)์ด 42(์ซ์)๋ ๊ฐ์ "42"(๋ฌธ์์ด)๋ ๊ฐ๊ณผ ๋ค๋ฅด๊ฒ ์ทจ๊ธํ๋ค๋ฉด, ๋ ๊ฐ์ ํ์ (์ซ์์ ๋ฌธ์์ด)์ด ์๋ก ๋ค๋ฅด๋ค.
๊ฑฐ์ ๋ชจ๋ ์๋ฐ์คํฌ๋ฆฝํธ ํ๋ก๊ทธ๋จ์์ ๋ค์ํ ๋ฐฉ์์ผ๋ก ๊ฐ์ ๋ณํ์ด ์ผ์ด๋๋ฏ๋ก ํ์ ์ ํ์คํ๊ฒ ์ธ์งํ๊ณ ์ฌ์ฉํ๋ ๊ฒ์ด ์ฆ์ํ๋ค.
# ๋ด์ฅ ํ์
์๋ฐ์คํฌ๋ฆฝํธ์๋ ๋ค์ 7๊ฐ์ง ๋ด์ฅ ํ์ ์ด ์๋ค.
- null
- undefined
- boolean
- number
- string
- object
- symbol
typeof
์ฐ์ฐ์๋ฅผ ์ฌ์ฉํด์ ๊ฐ ํ์
์ ์ ์ ์๋๋ฐ 7๊ฐ์ง์ ๋ด์ฅ ํ์
๊ณผ 1:1๋ก ์ ํํ๊ฒ ๋งค์นญ๋์ง ์๋๋ค.
null
์ ๊ฒฝ์ฐ ์๋์ ๊ฐ์ด ๊ฒฐ๊ณผ ๊ฐ์ผ๋ก null
์ด ๋ฐํ๋์ง ์๊ณ object
๋ฅผ ๋ฐํํ๋ค.
typeof null === 'object' // true
์ถ๊ฐ์ ์ผ๋ก typeof
๊ฐ ๋ฐํํ๋ ๋ฌธ์์ด๋ก function
์ด ์๋ค.
๋ช
์ธ๋ฅผ ์ดํด๋ณด๋ฉด function
์ object
์ 'ํ์ ํ์
'์ด๋ฉฐ 'ํธ์ถ ๊ฐ๋ฅํ ๊ฐ์ฒด'๋ผ๊ณ ๋ช
์๋์ด ์๋ค.
# ๊ฐ์ ํ์ ์ ๊ฐ์ง๋ค
๊ฐ์๋ ํ์
์ด ์์ง๋ง, ๋ณ์์ ๋ฐ๋ก ํ์
์ด๋ ์๋ค. ๋ณ์๋ ์ธ์ ๋ผ๋ ์ด๋ค ํํ์ ๊ฐ์ด๋ผ๋ ๊ฐ์ง ์ ์๋ค.
์๋ฐ์คํฌ๋ฆฝํธ์์๋ 'ํ์
๊ฐ์ '๋ฅผ ํ์ง ์๊ธฐ ๋๋ฌธ์, ๋ณ์์ typeof
์ฐ์ฐ์๋ฅผ ๋์ด๋ณด๋ ๊ฒ์ ๋ณ์์ ํ์
์ ๋ฌผ์ด๋ณด๋ ์ง๋ฌธ๊ณผ ๊ฐ์ง๋ง, ์ค์ ๋ก ํ์
์ด๋ ๊ฐ๋
์ด ๋ณ์์ ์์ผ๋ฏ๋ก ๋ณ์์ ๋ค์ด์๋ ๊ฐ์ ํ์
์ ๋ฌผ์ด๋ณด๋ ๊ฒ๊ณผ ๊ฐ๋ค.
# ๊ฐ์ด ์๋ vs ์ ์ธ๋์ง ์์
๊ฐ์ด ์๋(undefined
) : ์ ๊ทผ ๊ฐ๋ฅํ ์ค์ฝํ์ ๋ณ์๊ฐ ์ ์ธ๋์์ผ๋ ๊ฐ์ด ํ ๋น๋์ง ์์ ์ํ
์ ์ธ๋์ง ์์(undefined
) : ์ ๊ทผ ๊ฐ๋ฅํ ์ค์ฝํ์ ๋ณ์ ์์ฒด๊ฐ ์ ์ธ์กฐ์ฐจ ๋์ง ์์ ์ํ
์ ์ธ๋์ง ์์ ๋ณ์์ typeof
์ฐ์ฐ ๊ฒฐ๊ณผ ๋๋ฌธ์ ๋ ์ํ๊ฐ ๊ฐ๋ค๊ณ ์๊ฐํ ์ ์์ง๋ง ์์ฐํ ๋ค๋ฅธ ๊ฐ๋
์ด๋ค.
let a;
typeof a; // "undefined"
typeof b; // "undefined"
2
3
typeof
์ฐ์ฐ์ผ๋ก ์ธํด ๊ฐ๋
์ ํผ๋์ด ๋ฐ์ํ ์ ์์ง๋ง, ๋ค์๊ณผ ๊ฐ์ด ์์ ๊ฐ๋ ์ญํ ์ ํ ์๋ ์๋ค.
let a = 2, c = 0;
if ( b ) { // ReferenceError: b is not defined
c = a + b;
}
if ( typeof b !== 'undefined' ) {
c = a + b;
}
2
3
4
5
6
7
8
9
# ๊ฐ
# ๋ฐฐ์ด
์๋ฐ์คํฌ๋ฆฝํธ ๋ฐฐ์ด์ ํ์ ์ด ์๊ฒฉํ ๋ค๋ฅธ ์ธ์ด์ ๋ฌ๋ฆฌ ๋ฌธ์์ด, ์ซ์, ๊ฐ์ฒด ์ฌ์ง์ด ๋ค๋ฅธ ๋ฐฐ์ด์ด๋ ์ด๋ค ํ์ ์ ๊ฐ์ด๋ผ๋ ๋ด์ ์ ์๋ ๊ทธ๋ฆ์ด๋ค.
let a = [1, '2', [3]];
๋ฐฐ์ด์ ํฌ๊ธฐ๋ฅผ ๋ฏธ๋ฆฌ ์ง์ ํ์ง ์๊ณ ๋ ์ ์ธํ ์ ์์ผ๋ฉฐ ์ํ๋ ์์น์ ๊ฐ์ ์ถ๊ฐํ ์ ์๋ค. ์ด๋ก ์ธํด์ ์ค๊ฐ์ '๋น ์ฌ๋กฏ'์ด ์๊ธธ ์ ์๋ค.
let a = [];
a[0] = 1;
a[2] = 3;
a[1]; // undefined
a.length; // 3
2
3
4
5
6
7
๋ฐฐ์ด ์ธ๋ฑ์ค๋ ์ซ์์ธ๋ฐ, ๋ฐฐ์ด ์์ฒด๋ ํ๋์ ๊ฐ์ฒด์ฌ์ ํค/ํ๋กํผํฐ ๋ฌธ์์ด์ ์ถ๊ฐํ ์ ์๋ค.
(ํ์ง๋ง ๋ฐฐ์ด length๊ฐ ์ฆ๊ฐํ์ง๋ ์๋๋ค)
let a = [];
a[0] = 1;
a['footer'] = 2;
a.length; // 1
a['footer']; // 2
a.footer; // 2
2
3
4
5
6
7
8
ํค๋ก ๋ฃ์ ๋ฌธ์์ด ๊ฐ์ด 10์ง์ ์ซ์๋ก ํ์ ์ด ๋ฐ๋๋ฉด, ๋ฌธ์์ด ํค๊ฐ ์๋ ์ซ์ ํค๋ฅผ ์ฌ์ฉํ ๊ฒ ๊ฐ์ ๊ฒฐ๊ณผ๊ฐ ์ด๋๋๋ค.
let a = [];
a['13'] = 42;
a.length; // 14
2
3
4
TIP
๋ฌธ์์ด ํ์ ์ ํค/ํ๋กํผํฐ ์ฌ์ฉ์ด ํ์ํ ๊ฒฝ์ฐ์๋ ๋ฐฐ์ด๋ณด๋ค๋ ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ์ถ์ฒํ๋ค.
# ๋ฌธ์์ด
ํํ ๋ฌธ์์ด์ ๋จ์ง ๋ฌธ์์ ๋ฐฐ์ด์ด๋ผ๊ณ ์๊ฐํ์ง๋ง ์๋ฐ์คํฌ๋ฆฝํธ์์๋ ์ค์ ๋ก ์๊น์๋ง ๋น์ทํ ๋ฟ ๋ฌธ์ ๋ฐฐ์ด๊ณผ ๊ฐ์ง ์๋ค.
let a = 'foo';
let b = ['f', 'o', 'o'];
2
๋ฌธ์์ด์ ๋ฐฐ์ด๊ณผ ๊ฒ๋ชจ์ต์ด ๋ฎ์๋ค.(์ ์ฌ๋ฐฐ์ด) ๋ ๋ค
length
ํ๋กํผํฐ,indexOf()
,concat()
๋ฉ์๋๋ฅผ ๊ฐ์ง๋ค.
๊ฒ๋ชจ์ต์ ๋น์ทํ์ง๋ง ๋ฌธ์์ด์ ๋ถ๋ณ ๊ฐ(immutable)์ด๊ณ ๋ฐฐ์ด์ ๊ฐ๋ณ ๊ฐ(mutable)์ด๋ค. ๋ฐฐ์ด์ฒ๋ผ(a[1]
) ๋ฌธ์์ด์ ํน์ ๋ฌธ์๋ฅผ ์ ๊ทผํ๋ ํํ๊ฐ ์๋ฐ์คํฌ๋ฆฝํธ ์์ง์์ ์ ํจํ ๊ฒ์ ์๋๋ค.(์ธํฐ๋ท ์ต์คํ๋ก๋ฌ ๊ตฌ๋ฒ์ ์์๋ ๋ฌธ๋ฒ ์๋ฌ๋ก ์ธ์ํ๋ค.)
๋ฌธ์์ด์ ๋ถ๋ณ ๊ฐ์ด๋ฏ๋ก ๋ฌธ์์ด ๋ฉ์๋๋ ๊ทธ ๋ด์ฉ์ ๋ฐ๋ก ๋ณ๊ฒฝํ๋ ๊ฒ์ด ์๋๊ณ ์๋ก์ด ๋ฌธ์์ด์ ์์ฑํ ํ ๋ฐํํ๋ค.
TIP
๋ฌธ์์ด์ ๋ค๋ฃฐ ๋ ์ ์ฉํ ๋๋ถ๋ถ์ ๋ฐฐ์ด ๋ฉ์๋๋ ์ฌ์ค์ ๋ฌธ์์ด์ ์ธ ์ ์์ง๋ง, ๋ฌธ์์ด์ ๋ํด ๋ถ๋ณ ๋ฐฐ์ด ๋ฉ์๋๋ฅผ ๋น๋ ค ์ธ ์๋ ์๋ค.
let a = 'foo';
a.join; // undefined
a.map; // undefined
let c = Array.prototype.join.call( a, '-' );
let d = Array.prototype.map.call( a, (value) => {
return value.toUpperCase() + '.';
}).join('');
c; // "f-o-o"
d; // "F.O.O."
2
3
4
5
6
7
8
9
10
11
12
WARNING
reverse
๋ฉ์๋๋ ๊ฐ๋ณ ๋ฉ์๋์ด๊ธฐ ๋๋ฌธ์ ๋ฌธ์์ด์์ ์ฌ์ฉํ ์ ์๋ค.
let a = 'foo';
a.reverse; // undefined
Array.prototype.reverse.call( a ); // Uncaught TypeError
2
3
4
# ์ซ์
์๋ฐ์คํฌ๋ฆฝํธ์ ์ซ์ ํ์
์ number
๊ฐ ์ ์ผํ๋ฉฐ ์ ์, ๋ถ๋ ์์์ ์ซ์๋ฅผ ๋ชจ๋ ํฌํจํ๋ค.
์๋ฐ์คํฌ๋ฆฝํธ ์ซ์ ๋ฆฌํฐ๋ด์ 10์ง์ ๋ฆฌํฐ๋ด๋ก ํ์ํ๋ค.
let a = 42;
let b = 42.3;
let c = .42; // ์์์ ์ 0์ ์๋ต ๊ฐ๋ฅ.
let d = 42.; // ์์์ ๋ค 0์ผ ๋๋ ์๋ต ๊ฐ๋ฅ.
2
3
4
5
์์ฃผ ํฌ๊ฑฐ๋ ์์ ๊ฐ์ ์ง์ํ์ผ๋ก ํํํ๋ค.
let a = 5E10;
a; // 50000000000
let b = 1 / a; // 2e-11
2
3
์ซ์ ๊ฐ์ Number
๊ฐ์ฒด ๋ํผ๋ก ๋ฐ์ฑํ ์ ์๊ธฐ ๋๋ฌธ์ Number.prototype
๋ฉ์๋๋ก ์ ๊ทผํ ์ ์๋ค.
let a = 42.59;
a.toFixed( 0 ); // "43"
a.toFixed( 1 ); // "42.6"
a.toFixed( 2 ); // "42.59"
a.toFixed( 3 ); // "42.590"
2
3
4
5
6
TIP
toFixed
ํจ์๋ ์ซ์ ๊ฐ์ ๋ฌธ์์ด ํํ๋ก ๋ฐํํ๋ค.
Number.prototype
๋ฉ์๋๋ ์ซ์ ๋ฆฌํฐ๋ด์์ ๋ฐ๋ก ์ ๊ทผํ ์ ์์ผ๋ฏ๋ก ๊ตณ์ด ๋ณ์๋ฅผ ๋ง๋ค์ด ํ ๋นํ์ง ์์๋ ๋์ง๋ง .
์์์ ์ผ ๊ฒฝ์ฐ์ ํ๋กํผํฐ ์ ๊ทผ์๊ฐ ์๋ ์ซ์ ๋ฆฌํฐ๋ด์ ์ผ๋ถ๋ก ํด์๋๋ฏ๋ก ์กฐ์ฌํด์ผํ๋ค.
// ์๋ชป๋ ๊ตฌ๋ฌธ
42.toFixed( 3 ); // SyntaxError
// ์ฌ๋ฐ๋ฅธ ๊ตฌ๋ฌธ
(42).toFixed( 3 ); // "42.000"
0.42.toFixed( 3 ); // "0.420"
42..toFixed( 3 ); // "42.000"
42 .toFixed( 3 ); // "42.000"
2
3
4
5
6
7
8
# ํน์ ๊ฐ
# Undefined
Undefined
ํ์
์ ๊ฐ์ undefined
๋ฐ์ ์๋ค. ๋์จํ ๋ชจ๋์์๋ ์ ์ญ ์ค์ฝํ์์ undefined
์๋ณ์์ ๊ฐ์ ํ ๋นํ ์ ์๋ค.
function foo () {
undefined = 2; // ์๋ฌ ๋ฐ์ํ์ง ์์.
}
foo();
2
3
4
5
WARNING
undefined
์๋ณ์์ ๊ฐ์ ํ ๋นํ๋ ๊ฒ์ ๊ถ์ฅํ์ง ์๋๋ค.
# void
์ฐ์ฐ์
ํํ์ void __
๋ ์ด๋ค ๊ฐ์ด๋ ๋ฌดํจ๋ก ๋ง๋ค์ด ํญ์ ๊ฒฐ๊ด๊ฐ์ undefined
๋ก ๋ง๋ ๋ค. ๊ธฐ์กด ๊ฐ์ ๊ฑด๋๋ฆฌ์ง ์๊ณ ์ฐ์ฐ ํ ๊ฐ์ ๋ณต๊ตฌํ ์ ์๋ค.
let a = 42;
console.log( void a, a ); // undefined 42
2
3
void
์ฐ์ฐ์๋ ๊ฐ์ด ์กด์ฌํ๋ ๊ณณ์์ ๊ทธ ๊ฐ์ด undefined
๊ฐ ๋์ด์ผ ์ข์ ๊ฒฝ์ฐ์ ์ฌ์ฉํ๋ค.
# ํน์ ์ซ์ - NaN
์ํ ์ฐ์ฐ ์ ๋ ํผ์ฐ์ฐ์๊ฐ ์ ๋ถ ์ซ์๊ฐ ์๋ ๊ฒฝ์ฐ ์ ํจํ ์ซ์๊ฐ ๋์ฌ ์ ์์ ๋์ ๊ฒฐ๊ด๊ฐ์ผ๋ก ๊ธ์ ๊ทธ๋๋ก '์ซ์ ์๋'์ ๋ํ๋ด์ง๋ง, '์ซ์ ์๋' ๋ณด๋ค๋ '์ ํจํ์ง ์์ ์ซ์', '์คํจํ ์ซ์'๋ก ์ดํดํ๋ ๊ฒ์ด ๋ ์ ํํ๋ค.
NaN
์ ์ฌ์ฉํ ๋ ์ฃผ์ํด์ผํ๋ ์ฌํญ์ ๋ค์๊ณผ ๊ฐ๋ค.
// ์ซ์๊ฐ ์๋์ง๋ง typeof ๊ฐ์ 'number'์ ๊ฐ๋ค.
let a = 2 / 'foo'; // NaN
typeof a === 'number'; // true
// NaN์ ๋ค๋ฅธ ์ด๋ค NaN๊ณผ๋ ๋๋ฑํ์ง ์๋ค.(์ ์ผ๋ฌด์ดํ ๊ฐ)
let b = 2 / 'foo'; // NaN
b === NaN; // false
2
3
4
5
6
7
NaN
์ฌ๋ถ๋ฅผ ํ์ธํ๋ ๋ฐฉ๋ฒ์ผ๋ก isNaN()
๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ด ์๋ค. ํ์ง๋ง isNaN()
์ '์ธ์ ๊ฐ์ด ์ซ์์ธ์ง ์ฌ๋ถ๋ฅผ ํ๊ฐ'ํ๋ ๊ธฐ๋ฅ์ ํ๊ธฐ ๋๋ฌธ์ ๋ค์๊ณผ ๊ฐ์ ๊ฒฐ๊ณผ๊ฐ ๋ฐ์ํ๋ค.
let a = 2 / 'foo';
let b = 'foo';
a; // NaN
b; // "foo"
isNaN( a ); // true
isNaN( b ); // true
2
3
4
5
6
7
8
TIP
ES6๋ถํฐ ์ ๊ณต๋๋ Number.isNaN()
์ ์ฌ์ฉํ๋ฉด ์ํ๋ ๊ฒฐ๊ณผ๋ฅผ ์ป์ ์ ์๋ค.
# ๊ฐ vs ๋ ํผ๋ฐ์ค
๋ค๋ฅธ ์ธ์ด์์ ๊ฐ์ ์ฌ์ฉํ๋ ๊ตฌ๋ฌธ์ ๋ฐ๋ผ ๊ฐ-๋ณต์ฌ ๋๋ ๋ ํผ๋ฐ์ค ๋ณต์ฌ์ ํํ๋ก ํ ๋น/์ ๋ฌํ๋ค. ๋ค๋ฅธ ์ธ์ด์ ๋ค๋ฅด๊ฒ ์๋ฐ์คํฌ๋ฆฝํธ์์๋ ๊ฐ ๋๋ ๋ ํผ๋ฐ์ค์ ํ ๋น ๋ฐ ์ ๋ฌ์ ์ ์ดํ๋ ๊ตฌ๋ฌธ ์์๊ฐ ์ ํ ์๋ค. ๋์ , ๊ฐ์ ํ์ ๋ง์ผ๋ก ๊ฐ-๋ณต์ฌ, ๋ ํผ๋ฐ์ค-๋ณต์ฌ ๋ ์ค ํ์ชฝ์ด ๊ฒฐ์ ๋๋ค.
let a = 2;
let b = a; // 'b'๋ ์ธ์ ๋ 'a'์์ ๊ฐ์ ๋ณต์ฌํ๋ค.
b++;
a; // 2
b; // 3
let c = [1, 2, 3];
let d = c; // 'd'๋ ๊ณต์ ๋ '[1, 2, 3]'๊ฐ์ ๋ ํผ๋ฐ์ค์ด๋ค.
d.push( 4 );
c; // [1, 2, 3, 4]
d; // [1, 2, 3, 4]
2
3
4
5
6
7
8
9
10
11
null
, undefined
, string
, number
, boolean
๊ทธ๋ฆฌ๊ณ symbol
๊ฐ์ ๋จ์ ๊ฐ์ ์ธ์ ๋ ๊ฐ-๋ณต์ฌ ๋ฐฉ์์ผ๋ก ํ ๋น/์ ๋ฌ๋๋ค. ๊ฐ์ฒด๋ ํจ์ ๋ฑ ํฉ์ฑ ๊ฐ์ ํ ๋น/์ ๋ฌ์ ๋ฐ๋์ ๋ ํผ๋ฐ์ค ์ฌ๋ณธ์ ์์ฑํ๋ค.
๋ฐฐ์ด ๊ฐ์ ํฉ์ฑ ๊ฐ์ ๊ฐ-๋ณต์ฌ์ ์ํด ์ ๋ฌํ๋ ค๋ฉด ์์ ๊ฐ์ ์ฌ๋ณธ์ ๋ง๋ค์ด ์ ๋ฌํ ๋ ํผ๋ฐ์ค๊ฐ ์๋ณธ์ ๊ฐ๋ฆฌํค์ง ์๊ฒ ํ๋ฉด ๋๋ค.
foo( a.slice() );
WARNING
์์ ๋ณต์ฌ์ ์ํด ์ฌ๋ณธ์ ์์ฑํ ๊ฒฝ์ฐ, ๋ด๋ถ์ ์๋ ๊ฐ์ ๋ณ๊ฒฝ์ ์๋ณธ์ ์ํฅ์ ์ค ์ ์๋ค.
๋ฐ๋๋ก ์์ ๊ฐ์ ๋ ํผ๋ฐ์ค์ฒ๋ผ ๋ฐ๋ ๊ฐ์ด ๋ฐ๋ก ๋ฐ์๋๋๋ก ๋๊ธฐ๋ ค๋ฉด ์์ ๊ฐ์ ํฉ์ฑ ๊ฐ(๊ฐ์ฒด, ๋ฐฐ์ด ๋ฑ)์ผ๋ก ๊ฐ์ธ์ผํ๋ค.
const foo = (wrapper) => {
wrapper.a = 42;
}
const obj = { a: 2 };
foo( obj );
obj.a; // 42
2
3
4
5
6
7
โ * Event Loop * ๋ ์ง์ ์๊ฐ โ