๐ ๋ชจ๋์๋ฐ์คํฌ๋ฆฝํธ : ECMAScript 6(ES6, ๋๋ ES2015)์ 2015๋ ๋ฐํ๋ ์๋ฐ์คํฌ๋ฆฝํธ ํ์ค์ ์ฃผ์ ์ ๋ฐ์ดํธ
๊ณต๋ถ๋ฐฉ ์๋ฃ๋ keysub๊ฐ AI๋ฅผ ํ์ฉํด ์์ฑยทํธ์งํ์ต๋๋ค.
๐ ์ฐธ๊ณ ์ฌํญ: ECMAScript ์ฃผ์ ์
๋ฐ์ดํธ ์ด๋ ฅ (ํด๋ฆญํด์ ํผ์น๊ธฐ)
ES6 (ES2015)
- ์๋ก์ด ๋ณ์ ์ ์ธ ๋ฐฉ์: ๊ธฐ์กด์ var ๋์ ๋ธ๋ก ๋ฒ์(block scope)๋ฅผ ๊ฐ์ง๋ let๊ณผ ์์ ์ ์ธ์ ์ํ const๊ฐ ์ถ๊ฐ๋์ด ๋ณ์ ๊ด๋ฆฌ์ ์์ ์ฑ์ด ๋์์ก์ต๋๋ค.
- ํ ํ๋ฆฟ ๋ฆฌํฐ๋ด (Template Literals): ๋ฐฑํฑ(`)์ ์ฌ์ฉํ์ฌ ๋ฌธ์์ด ๋ด๋ถ์ ๋ณ์๋ฅผ ์ฝ๊ฒ ์ฝ์ ํ๊ฑฐ๋ ์ค๋ฐ๊ฟ์ ํํํ ์ ์๊ฒ ๋์์ต๋๋ค.
- ๊ตฌ์กฐ ๋ถํด ํ ๋น (Destructuring): ๊ฐ์ฒด๋ ๋ฐฐ์ด์์ ํ์ํ ๊ฐ๋ง ๊ฐ๊ฒฐํ๊ฒ ์ถ์ถํ์ฌ ๋ณ์์ ํ ๋นํ ์ ์์ต๋๋ค.
- ํ์ดํ ํจ์ (Arrow Functions):
=>๋ฌธ๋ฒ์ ์ฌ์ฉํ์ฌ ํจ์๋ฅผ ๋ ๊ฐ๊ฒฐํ๊ฒ ์ ์ธํ ์ ์์ผ๋ฉฐ, this ๋ฐ์ธ๋ฉ์ด ์ ์ ์ผ๋ก ๊ฒฐ์ ๋ฉ๋๋ค. - ํด๋์ค (Classes): ๊ฐ์ฒด ์งํฅ ํ๋ก๊ทธ๋๋ฐ์ ๋ ์ง๊ด์ ์ผ๋ก ๊ตฌํํ ์ ์๋ ํด๋์ค ๋ฌธ๋ฒ์ด ๋์ ๋์์ต๋๋ค.
- Promise: ์ฝ๋ฐฑ ์ง์ฅ์ ํด๊ฒฐํ๊ธฐ ์ํ Promise ๊ฐ์ฒด๊ฐ ํ์ค์ผ๋ก ํฌํจ๋์์ต๋๋ค.
- ์ ๊ฐ ์ฐ์ฐ์ (...): ๊ธฐ์กด ๋ฐฐ์ด์ด๋ ๊ฐ์ฒด๋ฅผ ๊ฑด๋๋ฆฌ์ง ์๊ณ (๋ถ๋ณ์ฑ ์ ์ง) ์๋ก์ด ๋ณต์ฌ๋ณธ์ ๋ง๋ค๊ฑฐ๋ ํฉ์น ๋ ์ฌ์ฉํฉ๋๋ค.
- ๋ชจ๋ (import / export): ์ฝ๋๋ฅผ ์ฌ๋ฌ ํ์ผ๋ก ๋๋๊ณ ์กฐ๋ฆฝํ๋ ํ๋ ์๋ฐ์คํฌ๋ฆฝํธ ์ํ๊ณ์ ํ์ค์ ๋๋ค. ๋ชจ๋ํ (Modules): import์ export ๊ตฌ๋ฌธ์ ํตํด ์ฝ๋๋ฅผ ๋ ๋ฆฝ์ ์ธ ๋ชจ๋๋ก ๋๋๊ณ ๊ด๋ฆฌํ๋ ๋ค์ดํฐ๋ธ ๊ธฐ๋ฅ์ด ์๊ฒผ์ต๋๋ค.
- Map ๊ฐ์ฒด
- Set ๊ฐ์ฒด
ES7 (ES2016)
- Array.includes() (๋ฐฐ์ด ๋ด ํน์ ์์ ์กด์ฌ ์ฌ๋ถ ํ์ธ)
ES8 (ES2017)
- async / await (๋น๋๊ธฐ ์ฒ๋ฆฌ์ ํ์ค)
- Object.values() / Object.entries(): ๊ฐ์ฒด ์์ ์๋ ๊ฐ๋ค๋ง ๋ฝ์์ ๋ฐฐ์ด๋ก ๋ง๋ค๊ฑฐ๋, Key์ Value๋ฅผ ๋์์ ๋ฝ์ ๋ฐ๋ณต๋ฌธ์ ๋๋ฆด ๋ ๋งค์ฐ ์์ฃผ ์ฐ์ ๋๋ค.
ES11 (ES2020)
์ง๊ธ์ง๊ธํ ์๋ฌ ๋ฐฉ์ง ์ด ๋ ๊ฐ์ง๋ ์ค๋ฌด์์ TypeError๋ก ํ๋ฉด์ด ๋ป๋ ๊ฒ์ ๋ง์์ฃผ๋ ๊ตฌ์์์ ๋๋ค.
- ์ต์
๋ ์ฒด์ด๋ (?.): ๊ฐ์ฒด ์์ ๊ฐ์ฒด๋ฅผ ์ฐพ์ ๋, ์ค๊ฐ์ ๊ฐ์ด null์ด๊ฑฐ๋ undefined์ฌ๋ ์๋ฌ๋ฅผ ๋ด์ง ์๊ณ ์์ ํ๊ฒ undefined๋ฅผ ๋ฐํํฉ๋๋ค. (์:
user?.profile?.address) - ๋ ๋ณํฉ ์ฐ์ฐ์ (??): ๊ฐ์ด null์ด๊ฑฐ๋ undefined์ผ ๋๋ง ์ฐ์ธก์ ๊ธฐ๋ณธ๊ฐ์ ๋ณด์ฌ์ค๋๋ค. ๊ธฐ์กด
||์ฐ์ฐ์์ ๋ฒ๊ทธ(์ซ์ 0์ ๊ฑฐ์ง์ผ๋ก ํ๋จํ๋ ๋ฌธ์ )๋ฅผ ์๋ฒฝํ ํด๊ฒฐํ์ต๋๋ค. - Promise.allSettled() (์ฌ๋ฌ ํ๋ก๋ฏธ์ค์ ๊ฒฐ๊ณผ๋ฅผ ๋ชจ๋ ๋ฐฐ์ด๋ก ๋ฐํ)
ES12 (ES2021)
- String.replaceAll() (๋ฌธ์์ด ๋ด ๋ชจ๋ ํจํด ๊ต์ฒด)
- ๊ณผ๊ฑฐ์๋ ์ ๊ทํํ์(
/๋จ์ด/g)์ ์จ์ผ๋ง ํ ์คํธ ์์ ๋ชจ๋ ํน์ ๋จ์ด๋ฅผ ๋ฐ๊ฟ ์ ์์์ง๋ง, ์ด์ ๋ ์ด ๋ฉ์๋ ํ๋๋ก ์ง๊ด์ ์ด๊ณ ๊น๋ํ๊ฒ ์ ์ฒด ๊ต์ฒด๊ฐ ๊ฐ๋ฅํด์ก์ต๋๋ค.
๐ก ์ด ๊ฐ์ข์์๋ ์ต์ ์๋ฐ์คํฌ๋ฆฝํธ์์ ๋ฌ๋ผ์ง ๊ฐ๋ ์ ์ค์ฌ์ผ๋ก ์ ๋ฆฌํฉ๋๋ค.
1. ๋ณ์
1.1 ๋ณ์ ์ ์ธ
var, let, const์ ์ฐจ์ด๋ ํฌ๊ฒ ์ฌํ ๋น, ์ค๋ณต ์ ์ธ, ๊ทธ๋ฆฌ๊ณ ์ค์ฝํ(์ ํจ ๋ฒ์)๋ก ๋๋. ํ๋ ์๋ฐ์คํฌ๋ฆฝํธ์์๋ var๋ฅผ ๊ฑฐ์ ์ฐ์ง ์์.
[์ฃผ์ ์ฐจ์ด์ ์์ฝ]
๊ตฌ๋ถ var let const
์ฌํ ๋น ๊ฐ๋ฅ ๊ฐ๋ฅ ๋ถ๊ฐ๋ฅ(์์)
์ค๋ณต์ ์ธ ๊ฐ๋ฅ(์ํ) ๋ถ๊ฐ๋ฅ ๋ถ๊ฐ๋ฅ
์ค์ฝํ ํจ์๋จ์(Function) ๋ธ๋ก ๋จ์ ({ }) ๋ธ๋ก ๋จ์ ({ })
ํธ์ด์คํ
์ ์ธ์ ์ฌ์ฉ๊ฐ๋ฅ(undefined) ์ ์ธ ์ ์ฌ์ฉ ๋ถ๊ฐ (์๋ฌ) ์ ์ธ ์ ์ฌ์ฉ ๋ถ๊ฐ (์๋ฌ)
1.2 ์์
๐จ 1.2.1. ์ค๋ณต ์ ์ธ
var user = "์ฒ ์";
var user = "์ํฌ";
console.log(user); // "์ํฌ"
// [let / const] - ์ค๋ณต ์ ์ธ ๋ถ๊ฐ
let score = 100;
// let score = 200; // ์๋ฌ ๋ฐ์: SyntaxError (์ด๋ฏธ ์ ์ธ๋ ๋ณ์์)
const ID = "admin";
// const ID = "guest"; // ์๋ฌ ๋ฐ์: SyntaxError (์ด๋ฏธ ์ ์ธ๋ ๋ณ์์)
const ID_OBJ = {id1: 1, id2: 2};
ID_OBJ.id1 = 3;
console.log(ID_OBJ); // Object {id1: 3, id2: 2} // const๋ก ์ ์ธํด๋ ๊ฐ์ฒด์ด๊ฑฐ๋ ๋ฐฐ์ด์ผ ๊ฒฝ์ฐ ํ๋กํผํฐ, ํ๋กํผํฐ ๊ฐ์ ์์ ๊ฐ๋ฅ
๐ก๏ธ 1.2.2. ์ค์ฝํ var๋ ํจ์ ์์์ ์ ์ธํ ๊ฒฝ์ฐ ํจ์ ๋ฐ์ผ๋ก๋ง ์ ๋๊ฐ๋ฉด ์ด๋์๋ ํตํ์ง๋ง, let๊ณผ const๋ ์์ ์ ๊ฐ์ผ ์ค๊ดํธ { } (๋ธ๋ก)๋ฅผ ์ ๋ ๋ฒ์ด๋์ง ๋ชปํจ
if (true) {
var varName = "I am var";
}
console.log(varName); // "I am var" (๋ธ๋ก ๋ฐ์์๋ ์ ๊ทผ ๊ฐ๋ฅ)
// [let / const] - ๋ธ๋ก ์ค์ฝํ
if (true) {
let letName = "I am let";
const constName = "I am const";
console.log(letName); // "I am let" (์์์๋ ๋น์ฐํ ๊ฐ๋ฅ)
}
1.3 ๋ฐ์ดํฐ ํ์
๐ 1.3.1 ์ฌ๋ฒ : ์ ๋ ์ค๋ณต๋์ง ์๋ ์ ์ผ๋ฌด์ดํ ์๋ณ์.
- ์ ์ผ์ฑ:
Symbol()๋ก ์์ฑํ ๊ฐ์ ์ธํ(์ค๋ช )์ด ๊ฐ์๋ ์๋ก ๋ค๋ฅธ ๊ฐ์ผ๋ก ์ทจ๊ธ๋ฉ๋๋ค. - ๋ถ๋ณ์ฑ: ํ ๋ฒ ์์ฑ๋๋ฉด ๋ณ๊ฒฝํ ์ ์์ต๋๋ค.
- ์๋์ฑ: ์ผ๋ฐ์ ์ธ ๋ฃจํ(
for...in)๋Object.keys()๋ก๋ ์กฐํ๋์ง ์์, ๊ฐ์ฒด์ ๋น๋ฐ์ค๋ฌ์ด ํ๋กํผํฐ๋ฅผ ๋ง๋ค ๋ ์ ์ฉํฉ๋๋ค.
var sym = Symbol();
// 1. ์ฌ๋ฒ ์์ฑ (๊ดํธ ์์ ๋ฌธ์์ด์ ๋จ์ '์ค๋ช
'์ผ ๋ฟ์
๋๋ค)
const sym1 = Symbol('id');
const sym2 = Symbol('id');
console.log(sym1 === sym2); // false (์ค๋ช
์ด ๊ฐ์๋ ๊ฐ์ ๋ค๋ฆ)
// 2. ๊ฐ์ฒด์ ํค๋ก ์ฌ์ฉ
const user = {
name: "John",
[sym1]: 123 // ์ฌ๋ฒ์ ํค๋ก ํ ๋น
};
console.log(user[sym1]); // 123
// 3. ์๋์ฑ ํ์ธ (์ผ๋ฐ์ ์ธ ๋ฐฉ๋ฒ์ผ๋ก๋ ํค๊ฐ ๋ณด์ด์ง ์์)
for (let key in user) {
console.log(key); // "name"๋ง ์ถ๋ ฅ๋๊ณ sym1์ ๊ฑด๋๋
}
console.log(Object.keys(user)); // ["name"]
- ๊ฐ์ฒด๋ฅผ ๋ง๋ค ๋ ํค(key) ์์น์ ๋๊ดํธ []๋ฅผ ์ฌ์ฉํ๋ฉด, ๊ทธ ์์ ๋ด์ฉ์ ์ฝ๋๋ก ์คํํ ๊ฒฐ๊ณผ๊ฐ์ ํค๋ก ์ฐ๊ฒ ๋ค๋ ๋ป์ ๋๋ค.(์ด๊ฒ๋ ๋ชจ๋์๋ฐ์คํฌ๋ฆฝํธ)
๐ฌ 1.3.2 ํ
ํ๋ฆฟ ๋ฆฌํฐ๋ด
1.3.2.1 ๊ธฐ์กด์ ๋ฐ์ดํ(' ', " ") ๋์ ๋ฐฑํฑ(backtick, `)์ ์ฌ์ฉ.
1.3.2.2 ํ๋ ์ด์ค ํ๋ : ${...} ๋ฌธ๋ฒ์ ์ฌ์ฉํ์ฌ ๋ฌธ์์ด ์ค๊ฐ์ ๋ณ์๋ ์ฐ์ฐ์์ ์ง์ ๋ฃ์
const name = "Jquery";
const version = "1.0";
// 1. ๊ธฐ์กด ๋ฐฉ์ (ES5) - ๋ฐ์ดํ์ + ์ฐ์ฐ์ ์ฌ์ฉ
const oldWay = "ํ์ฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ " + name + "์ด๋ฉฐ ๋ฒ์ ์ " + version + "์
๋๋ค.";
// 2. ํ
ํ๋ฆฟ ๋ฆฌํฐ๋ด ๋ฐฉ์ (ES6) - ๋ฐฑํฑ๊ณผ ${} ์ฌ์ฉ
const newWay = `ํ์ฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ${name}์ด๋ฉฐ ๋ฒ์ ์ ${version}์
๋๋ค.`;
// 3. ์ค๋ฐ๊ฟ ์์
const multiLine = `
์ด๊ฒ์
์ฌ๋ฌ ์ค์
๊ทธ๋๋ก ์ถ๋ ฅํ๋ ์์ ์
๋๋ค.
`;
console.log(newWay);
console.log(multiLine);
1.3.2.3 ์ฌ์ฉ์
// 1. ๊ธฐ์กด ๋ฐฉ์
var html = "<div class='user'>" +
"\n <h1>์ด๋ฆ: " + this.name + "</h1>" +
"\n <p>๋์ด: " + this.age + "</p>" +
"\n</div>";
// 2. ํ
ํ๋ฆฟ ๋ฆฌํฐ๋ด
const htmlTemplate = `
<div class="user">
<h1>์ด๋ฆ: ${this.name}</h1>
<p>๋์ด: ${this.age}</p>
</div>
`;
2. ๊ฐ์ฒด
2.1 ๊ธฐ๋ณธ๊ฐ์ฒด๊ฐ๋
๐ 2.1.1 : ๊ฐ์ฒด๋ฆฌํฐ๋ด๋ก ๊ฐ์ฒด์์ฑ
var me = {name : "keysub", age: 11};
๐ 2.1.2. ๊ฐ์ฒด์์ ๊ฐ์ ์ฝ๊ฑฐ๋ ์ธ๋๋
me.name ํน์ me["age"]
โ 2.1.3. ์๋ ํ๋กํผํฐ ์ด๋ฆ์ ๊ฐ์ ๋์ ํ๋ฉด ์๋ก์ด ํ๋กํผํฐ๊ฐ ์ถ๊ฐ๋จ :
me.hobby = "์์";
โ 2.1.4. in ์ฐ์ฐ์๋ก ํ๋กํผํฐ๊ฐ ์๋์ง ํ์ธ :
console.log("hobby" in me); // true
2.2 ๊ฐ์ฒด ๋ฐ ์ปฌ๋ ์
(๋ฐฐ์ด, Set, Map)
โ๏ธ 2.2.1 ์์ฑ๋ช
์ถ์ฝ (Property Shorthand)
๋ณ์ ์ด๋ฆ๊ณผ ๊ฐ์ฒด์ ํค(key) ์ด๋ฆ์ด ๊ฐ๋ค๋ฉด ํ ๋ฒ๋ง ์จ๋ ๋จ.
const name = "์ํฌ";
const age = 30;
// ES5
const user5 = { name: name, age: age };
// ES6 (์ถ์ฝ)
const user6 = { name, age };
console.log(user6); // { name: "์ํฌ", age: 30 }
โก 2.2.2 ๋ฉ์๋ ์ถ์ฝ (Method Shorthand)
ํจ์๋ฅผ ์ ์ํ ๋ function ํค์๋ ์๋ต๊ฐ๋ฅ.
const dog = {
name: "๋ฉ๋ฉ์ด",
// ES5: bark: function() { ... }
bark() {
console.log("์์!");
}
};
๐งฎ 2.2.3 ๊ณ์ฐ๋ ์์ฑ ์ด๋ฆ (Computed Property Names)
๊ฐ์ฒด์ ํค ์ด๋ฆ์ ๋์ ์ผ๋ก(๋ณ์๋ ์ฐ์ฐ์์ ์ด์ฉํด) ์ ํ ์ ์์.
const prefix = "user";
const i = 1;
const member = {
[`${prefix}_${i}`]: "ํ๊ธธ๋" // 'user_1' ์ด๋ผ๋ ํค๊ฐ ์์ฑ๋จ
};
console.log(member.user_1); // "ํ๊ธธ๋"
2.3. Set (์ค๋ณต์ด ๋ถ๊ฐ๋ฅํ ์ฃผ๋จธ๋)
๐ซ 2.3.1 ๊ณผ๊ฑฐ์ ๋ฐฐ์ด(Array)๊ณผ Set์ ์ฐจ์ด
๊ณผ๊ฑฐ์๋ ์ฌ๋ฌ ๋ฐ์ดํฐ๋ฅผ ๋ด์ ๋ ๋ฌด์กฐ๊ฑด ๋ฐฐ์ด(Array)์ ์ผ์ต๋๋ค. ํ์ง๋ง ๋ฐฐ์ด์ ์ค๋ณต๋ ๊ฐ์ ํ์ฉํ์ฃ . ๋ง์ฝ "์ค๋ณต๋ ๋ฐ์ดํฐ๋ฅผ ๋ชจ๋ ์ง์์ค"๋ผ๋ ์๊ตฌ์ฌํญ์ด ๋ค์ด์ค๋ฉด ์ฝ๋๊ฐ ๊ฝค ์ง์ ๋ถํด์ก์ต๋๋ค. Set์ ํ์์ ์ผ๋ก ์ค๋ณต์ ์ ๋ ํ์ฉํ์ง ์๋ ์ฃผ๋จธ๋์ ๋๋ค. ๊ฐ์ ๊ฐ์ ์ฌ๋ฌ ๋ฒ ๋ฃ์ด๋ ํ๋๋ง ๋จ์ต๋๋ค.
๐ ๏ธ 2.3.2. Set ์์ฑํ๊ธฐ (์์ฑ์)
Set์ ๋ง๋๋ ๋ฐฉ๋ฒ์ ์์ฃผ ๊ฐ๋จํฉ๋๋ค. new ํค์๋๋ฅผ ์ฌ์ฉํด์ ๋ง๋ญ๋๋ค.
โ ๋น ์ฃผ๋จธ๋ ๋ง๋ค๊ธฐ
const mySet = new Set();
โก ์ฒ์๋ถํฐ ๋ฐ์ดํฐ๋ฅผ ๋ฃ์ด์ ๋ง๋ค๊ธฐ (๊ฐ์ฅ ๋ง์ด ์!) ๋ฐฐ์ด ๊ฐ์ '์ํํ ์ ์๋(iterable)' ๋ฐ์ดํฐ๋ฅผ ์์ฑ์ ์์ ๋ฃ์ด์ฃผ๋ฉด, ์ค๋ณต์ ์น ์ ๊ฑฐํ๊ณ Set์ ๋ง๋ค์ด ์ค๋๋ค.
// ์ซ์ 2์ 3์ด ์ค๋ณตํด์ ๋ค์ด์๋ ๋ฐฐ์ด์ ๋ฃ์ด๋ด
๋๋ค.
const numbers = new Set([1, 2, 2, 3, 3, 3, 4]);
console.log(numbers);
// ์ถ๋ ฅ: Set(4) { 1, 2, 3, 4 } <- ์ค๋ณต๋ 2์ 3์ด ๊น๋ํ๊ฒ ํ๋์ฉ๋ง ๋จ์์ต๋๋ค!
๐ช 2.3.3. Set์ด ๊ฐ์ง ๋ง๋ฒ์ ๋๊ตฌ๋ค (๋ฉ์๋์ ์์ฑ)
Set์ ๋ฐ์ดํฐ๋ฅผ ๋ค๋ฃจ๊ธฐ ์ํด ์์ฃผ ์ง๊ด์ ์ธ ๋ฉ์๋๋ค์ ์ ๊ณตํฉ๋๋ค.
โ ๋ฐ์ดํฐ ์ถ๊ฐํ๊ธฐ (add)
mySet.add("์ฌ๊ณผ");
mySet.add("๋ฐ๋๋");
mySet.add("์ฌ๊ณผ"); // ์ด๋ฏธ "์ฌ๊ณผ"๊ฐ ์์ผ๋ฏ๋ก ๋ฌด์๋จ!
console.log(mySet); // ์ถ๋ ฅ: Set(2) { '์ฌ๊ณผ', '๋ฐ๋๋' }
๐ก ํ: mySet.add(1).add(2); ์ฒ๋ผ ์ฒด์ด๋(๊ธฐ์ฐจ๋์ด)์ผ๋ก ๊ณ์ ์ด์ด ๋ถ์ผ ์๋ ์์ต๋๋ค.
โก ๋ฐ์ดํฐ ํ์ธํ๊ธฐ (has)
์ฃผ๋จธ๋ ์์ ํน์ ๊ฐ์ด ์๋์ง ๊ฒ์ฌํฉ๋๋ค. (๋ฐฐ์ด์ includes์ ๊ฐ์ ์ญํ ์ธ๋ฐ, ์๋๊ฐ ํจ์ฌ ๋น ๋ฆ
๋๋ค!)
console.log(mySet.has("์ฌ๊ณผ")); // ์ถ๋ ฅ: true
console.log(mySet.has("์๋ฐ")); // ์ถ๋ ฅ: false
โข ๋ฐ์ดํฐ ์ญ์ ํ๊ธฐ (delete / clear)
mySet.delete("๋ฐ๋๋"); // "๋ฐ๋๋"๋ง ์ ๋นผ์ ๋ฒ๋ฆผ
mySet.clear(); // ์ฃผ๋จธ๋ ์์ ์ ๋ถ ๋น์๋ฒ๋ฆผ! (์ด๊ธฐํ)
โฃ ํฌ๊ธฐ ํ์ธํ๊ธฐ (size ์์ฑ)
๋ฐฐ์ด์์๋ ๊ธธ์ด๋ฅผ ์๊ธฐ ์ํด .length๋ฅผ ์ฐ์ง๋ง, Set์์๋ ๋ฌด์กฐ๊ฑด .size๋ฅผ ์ฌ์ฉํด์ผ ํฉ๋๋ค.
const animalSet = new Set(["๊ฐ์์ง", "๊ณ ์์ด", "ํ ๋ผ"]);
console.log(animalSet.size); // ์ถ๋ ฅ: 3
๐ฏ 2.3.4. ์ค๋ฌด์์ Set์ ์ฐ๋ ๊ฐ์ฅ ์๋ฒฝํ ํ์ด๋ฐ
์ค๋ฌด์์ Set์ ์ธ์ ๊ฐ์ฅ ๋ง์ด ์ธ๊น์? ๋ฐ๋ก "๋ฐฐ์ด์ ์ค๋ณต์ ์ ๊ฑฐํ ๋"์ ๋๋ค. ์ด์ ์๋ ๋ฐฐ์ด์ ์ค๋ณต์ ์ ๊ฑฐํ๋ ค๋ฉด ๋ณต์กํ๊ฒ filter๋ ๋ฐ๋ณต๋ฌธ์ ๋๋ ค์ผ ํ์ง๋ง, Set๊ณผ ์ ๊ฐ ๊ตฌ๋ฌธ(...)์ ํฉ์น๋ฉด ๋จ ํ ์ค๋ก ๋๋ฉ๋๋ค.
const dirtyArray = ["ํ๊ธธ๋", "์ด์์ ", "ํ๊ธธ๋", "์ ๊ด์", "์ด์์ "];
// 1. ๋ฐฐ์ด์ Set์ผ๋ก ๋ง๋ค์ด์ ์ค๋ณต์ ๋ ๋ ค๋ฒ๋ฆฌ๊ณ ,
// 2. ๋ค์ ๋๊ดํธ []์ ... ์ ์จ์ ๋ฐฐ์ด๋ก ํฌ์ฅํฉ๋๋ค.
const cleanArray = [...new Set(dirtyArray)];
console.log(cleanArray);
// ์ถ๋ ฅ: [ 'ํ๊ธธ๋', '์ด์์ ', '์ ๊ด์' ]
2.4. Map (์ด๋ฆํ(Key)์ ๋ฌผ๊ฑด(Value)์ ํ ์์ผ๋ก ๋ฌถ์ด์ ๋ณด๊ดํ๋ ์ฌ๋ฌผํจ)
๐ก 2.4.1 Map์ ๋์
๋ฐฐ๊ฒฝ
์ฌ์ค ์๋ฐ์คํฌ๋ฆฝํธ์์๋ ์ผ๋ฐ ๊ฐ์ฒด({})๋ ํค์ ๊ฐ์ ์ ์ฅํ๋ ์ฌ๋ฌผํจ ์ญํ ์ ํ์ง๋ง, Map์ ๊ฐ์ฒด์ ๋จ์ ๋ค์ ์๋ฒฝํ๊ฒ ๋ณด์ํด์ ๋์จ ์ ๊ทธ๋ ์ด๋ ๋ฒ์ ์ ์ฌ๋ฌผํจ์ ๋๋ค.
๐๏ธ 2.4.2. Map ๋ค๋ฃจ๊ธฐ
2.4.2.1 Map ์์ฑํ๊ธฐ
โ ๋น ์ฌ๋ฌผํจ ๋ง๋ค๊ธฐ
const myMap = new Map();
โก ์ฒ์๋ถํฐ ๋ฐ์ดํฐ๋ฅผ ๋ฃ์ด์ ๋ง๋ค๊ธฐ Map์ ํค์ ๊ฐ์ด 'ํ ์'์ด์ด์ผ ํ๋ฏ๋ก, ๋ฐฐ์ด ์์ [ํค, ๊ฐ] ํํ์ ๋ฏธ๋ ๋ฐฐ์ด์ ๋ฃ์ด์ ์ด๊ธฐํํฉ๋๋ค.
const userMap = new Map([
["name", "ํ๊ธธ๋"],
["age", 25],
["role", "admin"]
]);
2.4.2.2 Map์ ๋ค๋ฃจ๋ ํต์ฌ ๋ฉ์๋
๋ฐ์ดํฐ ๋ฃ๊ธฐ/์์ ํ๊ธฐ (set) ์ฌ๋ฌผํจ(Key)์ ๋ฌผ๊ฑด(Value)์ ๋ฃ์ต๋๋ค. ์ด๋ฏธ ๊ฐ์ ์ด๋ฆ์ ํค๊ฐ ์๋ค๋ฉด ์๋ก์ด ๊ฐ์ผ๋ก ๋ฎ์ด์๋๋ค(์์ ).
myMap.set("color", "red");
myMap.set("size", 100);
myMap.set("color", "blue"); // "color" ํค์ ๊ฐ์ด "red"์์ "blue"๋ก ๋ฐ๋!
// Set์ฒ๋ผ ์ฒด์ด๋๋ ๊ฐ๋ฅํฉ๋๋ค.
myMap.set("a", 1).set("b", 2);
๋ฐ์ดํฐ ๊บผ๋ด๊ธฐ (get) ํค๋ฅผ ์ฃผ๋ฉด ํด๋น ๊ฐ์ ๋ฐํํฉ๋๋ค. ์๋ ํค๋ฅผ ์ฐพ์ผ๋ฉด undefined๊ฐ ๋์ต๋๋ค.
console.log(myMap.get("color")); // ์ถ๋ ฅ: "blue"
๋ฐ์ดํฐ ํ์ธํ๊ธฐ (has) ํด๋น ํค๊ฐ ์กด์ฌํ๋์ง ํ์ธํฉ๋๋ค. (๊ฐ์ ์๊ด์์ด ํค๋ง ์ฐพ์ต๋๋ค)
console.log(myMap.has("size")); // ์ถ๋ ฅ: true
๋ฐ์ดํฐ ์ญ์ ๋ฐ ํฌ๊ธฐ ํ์ธ (delete, clear, size)
myMap.delete("size"); // "size" ํค์ ๊ทธ ๊ฐ์ ์ญ์
console.log(myMap.size); // ํ์ฌ ๋ค์ด์๋ ๋ฐ์ดํฐ ์์ ๊ฐ์ ํ์ธ
myMap.clear(); // ์ฌ๋ฌผํจ ์ ์ฒด ๋น์ฐ๊ธฐ
๐ก 2.4.2.3. ์ ๊ตณ์ด ๊ฐ์ฒด({}) ๋์ Map์ ์ธ๊น์?
โ ํค(Key)๋ก ์๋ฌด๊ฑฐ๋ ์ธ ์ ์์ต๋๋ค! (๊ฐ์ฅ ๊ฐ๋ ฅํ ์ฐจ์ด) ์ผ๋ฐ ๊ฐ์ฒด๋ ๋ฌด์กฐ๊ฑด ํค๋ฅผ '๋ฌธ์์ด(String)'๋ก๋ง ๋ง๋ค์ด์ผ ํฉ๋๋ค. ์ซ์๋ฅผ ๋ฃ์ด๋ ๋ด๋ถ์ ์ผ๋ก ๋ฌธ์๋ก ๋ฐ๊ฟ๋ฒ๋ฆฌ์ฃ . ํ์ง๋ง Map์ ์ซ์, ๋ถ๋ฆฌ์ธ(true/false), ์ฌ์ง์ด ํจ์๋ ๋ค๋ฅธ ๊ฐ์ฒด๊น์ง๋ ํค(Key)๋ก ์ฌ์ฉํ ์ ์์ต๋๋ค.
const map = new Map();
// 1. ์ซ์๋ฅผ ํค๋ก ์ฌ์ฉ
map.set(1, "์ซ์ 1์
๋๋ค");
// 2. ๋ค๋ฅธ ๊ฐ์ฒด๋ฅผ ํค๋ก ์ฌ์ฉ (์ผ๋ฐ ๊ฐ์ฒด {} ์์๋ ์ ๋ ๋ถ๊ฐ๋ฅํ ๋ง๋ฒ!)
const kim = { id: 101, name: "๊น์ฒ ์" };
map.set(kim, "์ด ์ ์ ๋ VIP ํ์์
๋๋ค.");
console.log(map.get(kim)); // ์ถ๋ ฅ: "์ด ์ ์ ๋ VIP ํ์์
๋๋ค."
โก ๋ฐ์ดํฐ์ ํฌ๊ธฐ๋ฅผ ๋ฐ๋ก ์ ์ ์์ต๋๋ค.
์ผ๋ฐ ๊ฐ์ฒด๋ ์์ ๋ฐ์ดํฐ๊ฐ ๋ช ๊ฐ์ธ์ง ์๋ ค๋ฉด Object.keys(obj).length์ฒ๋ผ ๋ณต์กํ๊ฒ ๊ณ์ฐํด์ผ ํ์ง๋ง, Map์ map.size ํ๋๋ฉด ๋๋ฉ๋๋ค.
โข ๋ฃ์ ์์๋ฅผ ์๋ฒฝํ๊ฒ ๊ธฐ์ตํฉ๋๋ค. ์ผ๋ฐ ๊ฐ์ฒด๋ ๋ฐ์ดํฐ๋ฅผ ๋ฃ๊ณ ๋์ค์ ๋ฐ๋ณต๋ฌธ(for)์ ๋๋ ค๋ณด๋ฉด ์ฐ๋ฆฌ๊ฐ ๋ฃ์ ์์๋๋ก ๋์จ๋ค๋ ๋ณด์ฅ์ด ์์ต๋๋ค. ํ์ง๋ง Map์ ๋ฌด์กฐ๊ฑด ๋ฃ์ ์์๋๋ก๋ง ๋์ต๋๋ค.
๐๏ธ 2.5. Object.keys, values, entries : ๊ฐ์ฒด์ ๋ฐ์ดํฐ๋ฅผ ๋ฐฐ์ด๋ก ๋ณํํ์ฌ ๋ค๋ฃจ๊ธฐ
2.5.1. Object.keys() : ๊ฐ์ฒด์ 'ํค(Key)'๋ง ๋ฝ์์ ๋ฐฐ์ด๋ก ๋ง๋ค๊ธฐ
๐ ๊ฐ์ฒด์ ์ด๋ค ์์ฑ๋ค์ด ์๋์ง ํ์ธํ๊ฑฐ๋, ํค๋ฅผ ์ด์ฉํด ๋ฐ๋ณต๋ฌธ์ ๋๋ฆด ๋ ์ ์ฉํฉ๋๋ค.
const user = {
name: "์ํฅ๋ฏผ",
age: 32,
team: "ํ ํธ๋"
};
const keys = Object.keys(user);
console.log(keys);
// ์ถ๋ ฅ: ["name", "age", "team"]
// ์์ฉ: ํค ๋ฐฐ์ด์ ์ด์ฉํด ๋ฐ๋ณต๋ฌธ ๋๋ฆฌ๊ธฐ
keys.forEach(key => {
console.log(`${key}: ${user[key]}`);
});
2.5.2. Object.values() : ๊ฐ์ฒด์ '๊ฐ(Value)'๋ง ๋ฝ์์ ๋ฐฐ์ด๋ก ๋ง๋ค๊ธฐ (ES8)
๐ ํค ์ด๋ฆ์ ํ์ ์๊ณ , ์์ ๋ด๊ธด ๋ฐ์ดํฐ๋ค๋ง ํ์ํ ๋ ์ฌ์ฉํฉ๋๋ค.
const scores = {
korean: 90,
english: 85,
math: 100
};
const values = Object.values(scores);
console.log(values);
// ์ถ๋ ฅ: [90, 85, 100]
// ์์ฉ: ์ ์์ ํฉ๊ณ ๊ตฌํ๊ธฐ
const totalScore = values.reduce((acc, curr) => acc + curr, 0);
console.log(`์ด์ : ${totalScore}`); // ์ด์ : 275
2.5.3. Object.entries() : ํค์ ๊ฐ์ [Key, Value] ์์ ๋ฐฐ์ด๋ก ๋ง๋ค๊ธฐ (ES8)
๐ฏ ๊ฐ์ฒด๋ฅผ [ํค, ๊ฐ] ํํ์ 2์ฐจ์ ๋ฐฐ์ด๋ก ๋ณํํฉ๋๋ค. Map ๊ฐ์ฒด๋ก ๋ณํํ๊ฑฐ๋ ๋ณต์กํ ๊ฐ๊ณต์ ํ ๋ ํ์์
๋๋ค.
const user = {
id: 1,
role: "admin",
status: "active"
};
const entries = Object.entries(user);
console.log(entries);
/* ์ถ๋ ฅ:
[
["id", 1],
["role", "admin"],
["status", "active"]
]
*/
// ์์ฉ: for...of ๋ฌธ๊ณผ ๊ตฌ์กฐ ๋ถํด ํ ๋น ์กฐํฉ (์ค๋ฌด ์ถ์ฒ๐)
for (const [key, value] of Object.entries(user)) {
console.log(`${key} ํ๋์ ๊ฐ์ ${value}์
๋๋ค.`);
}
2.5.4. ์ค๋ฌด ํ: ๊ฐ์ฒด๋ฅผ ๋ค์ ๊ฐ์ฒด๋ก ๋ณํํ๊ธฐ (Object.fromEntries)
๐ ๋ฐฐ์ด ํํ๋ก ๋ณํ๋ ๋ฐ์ดํฐ๋ฅผ ๋ค์ ๊ฐ์ฒด๋ก ๋๋๋ฆฌ๊ณ ์ถ์ ๋ ์ฌ์ฉํฉ๋๋ค.
const arr = [
['name', '์ด๊ฐ์ธ'],
['age', 23]
];
const obj = Object.fromEntries(arr);
console.log(obj);
// ์ถ๋ ฅ: { name: "์ด๊ฐ์ธ", age: 23 }
๐ 2.6. includes : ํน์ ๊ฐ ํฌํจ ์ฌ๋ถ ํ์ธ (Array & String)
2.6.1. ๋ฐฐ์ด์์์ includes (Array.prototype.includes) - ES7
๐ ๊ณผ๊ฑฐ์ ๋ณต์กํ๋ indexOf() !== -1 ๋ฐฉ์์ ์๋ฒฝํ๊ฒ ๋์ฒดํ์ฌ true / false๋ฅผ ๋ฐํํฉ๋๋ค.
const fruits = ['apple', 'banana', 'mango'];
// [๊ณผ๊ฑฐ ES5 ๋ฐฉ์]
// indexOf๋ ๊ฐ์ ์ฐพ์ผ๋ฉด ์ธ๋ฑ์ค ๋ฒํธ(0, 1, 2...)๋ฅผ, ๋ชป ์ฐพ์ผ๋ฉด -1์ ๋ฐํํ์ต๋๋ค.
// ๊ทธ๋์ ํญ์ -1์ด ์๋์ง ๋น๊ตํ๋ ๊ฑฐ์ถ์ฅ์ค๋ฌ์ด ์ฝ๋๊ฐ ํ์ํ์ต๋๋ค.
if (fruits.indexOf('banana') !== -1) {
console.log("๋ฐ๋๋๊ฐ ์์ต๋๋ค!");
}
// [์ต์ ES7 ๋ฐฉ์] ๐
// ๊ทธ๋ฅ "์ด๊ฑฐ ํฌํจํ๊ณ ์์ด?" ๋ผ๊ณ ๋ฌผ์ด๋ณด๋ฉด ๊น๋ํ๊ฒ true/false๋ก ๋๋ตํด ์ค๋๋ค.
if (fruits.includes('banana')) {
console.log("๋ฐ๋๋๊ฐ ์์ต๋๋ค!");
}
// ๐ก (์ค์ ์ฐจ์ด์ ) NaN(Not a Number) ์ฐพ๊ธฐ
// indexOf๋ NaN์ ์ฐพ์ง ๋ชปํ์ง๋ง, includes๋ ์ ํํ๊ฒ ์ฐพ์๋
๋๋ค.
const arr = [1, 2, NaN];
console.log(arr.indexOf(NaN)); // -1 (๋ชป ์ฐพ์)
console.log(arr.includes(NaN)); // true (์ฐพ์)
2.6.2. ๋ฌธ์์ด์์์ includes (String.prototype.includes) - ES6
๐ ๊ธด ํ
์คํธ(๋ฌธ์์ด) ์์ ํน์ ๋จ์ด๊ฐ ํฌํจ๋์ด ์๋์ง๋ ์ฝ๊ฒ ๊ฒ์ฌํ ์ ์์ต๋๋ค.
const sentence = "์๋
ํ์ธ์, ์๋ฐ์คํฌ๋ฆฝํธ ๊ณต๋ถ ์ค์
๋๋ค.";
console.log(sentence.includes("์๋ฐ์คํฌ๋ฆฝํธ")); // true
console.log(sentence.includes("ํ์ด์ฌ")); // false
// ๐ก ํ: ๋ ๋ฒ์งธ ์ธ์๋ก '๊ฒ์ฌ๋ฅผ ์์ํ ์์น'๋ฅผ ์ง์ ํ ์ ์์ต๋๋ค.
// ์ธ๋ฑ์ค 10๋ฒ ์ดํ๋ถํฐ "์๋
"์ด ์๋์ง ์ฐพ์ต๋๋ค.
console.log(sentence.includes("์๋
", 10)); // false
2.6.3. ์ค๋ฌด ํ์ฉ ํ: ๋ค์ค ์กฐ๊ฑด๋ฌธ(OR) ๊น๋ํ๊ฒ ์ค์ด๊ธฐ
โ๏ธ if ๋ฌธ ์์ || (OR) ์ฐ์ฐ์๊ฐ ๋๋ฌด ๊ธธ์ด์ง ๋, ๋ฐฐ์ด๊ณผ includes๋ฅผ ์ฐ๋ฉด ์ฝ๋๊ฐ ํ๊ธฐ์ ์ผ๋ก ์งง์์ง๋๋ค.
const myFruit = 'apple';
// ๐จ [๋์ ์] ์กฐ๊ฑด์ด ๋์ด๋ ์๋ก ์ฝ๋๊ฐ ๋ฌดํ์ ๊ธธ์ด์ง
if (myFruit === 'apple' || myFruit === 'banana' || myFruit === 'mango') {
console.log("๊ณผ์ผ๋ฐ๊ตฌ๋์ ์๋ ๊ณผ์ผ์
๋๋ค.");
}
// โ
[includes ํ์ฉ] ๊ฒ์ฌํ ํญ๋ชฉ์ ๋ฐฐ์ด๋ก ๋ฌถ์ด๋ฒ๋ฆผ (์ค๋ฌด ๊ถ์ฅ๐)
const bucket = ['apple', 'banana', 'mango', 'grape', 'orange'];
if (bucket.includes(myFruit)) {
console.log("๊ณผ์ผ๋ฐ๊ตฌ๋์ ์๋ ๊ณผ์ผ์
๋๋ค.");
}
3. ๊ตฌ์กฐ ๋ถํด ํ ๋น
3.1. ๊ฐ์ฒด ๊ตฌ์กฐ ๋ถํด (Object Destructuring) :
๊ฐ์ฒด๋ ๋ฐ์ดํฐ๋ฅผ ์ถ์ถํ ๋ 'ํค(Key) ์ด๋ฆ'์ ๊ธฐ์ค์ผ๋ก ๋ณ์๋ฅผ ๋ง๋ญ๋๋ค.
const user = {
name: "์ํฅ๋ฏผ",
age: 32,
team: "ํ ํธ๋"
};
// [ES5 ๋ฐฉ์] ํ๋์ฉ ๋ณ์๋ฅผ ๋ง๋ค์ด ๋์
ํจ
var name = user.name;
var age = user.age;
// [ES6 ๋ฐฉ์] ํ ๋ฒ์ ๋ณ์๋ฅผ ์์ฑํ๊ณ ํ ๋นํจ
const { name, age, team } = user;
console.log(name); // "์ํฅ๋ฏผ"
console.log(team); // "ํ ํธ๋"
// ๋ง์ฝ ๋ณ์ ์ด๋ฆ์ ๋ฐ๊พธ๊ณ ์ถ๋ค๋ฉด? (์ด๋ฆ: ์์ด๋ฆ)
const { name: userName, age: userAge } = user;
console.log(userName); // "์ํฅ๋ฏผ"
3.2. ๋ฐฐ์ด ๊ตฌ์กฐ ๋ถํด (Array Destructuring) :
๋ฐฐ์ด์ ํค๊ฐ ์์ผ๋ฏ๋ก '์์(์ธ๋ฑ์ค)'๋ฅผ ๊ธฐ์ค์ผ๋ก ๋ณ์๋ฅผ ๋ง๋ญ๋๋ค.
const colors = ["Red", "Green", "Blue"];
// [ES5 ๋ฐฉ์] ํ๋์ฉ ๋ณ์๋ฅผ ๋ง๋ค์ด ๋์
ํจ
var first = colors[0];
var second = colors[1];
var third = colors[2];
// [ES6 ๋ฐฉ์] ๋๊ดํธ []๋ฅผ ์ฌ์ฉํจ
const [first, second, third] = colors;
console.log(first); // "Red"
console.log(second); // "Green"
// ํน์ ์์๋ฅผ ๊ฑด๋๋ฐ๊ณ ์ถ์ ๋ (์ผํ ํ์ฉ)
const [first_color , , third_color] = colors;
console.log(third_color); // "Blue"
3.3. ์ค๋ฌด์์ ๋น์ ๋ฐํ๋ ์๊ฐ
๐ผ 3.3.1 ํจ์์ ๋งค๊ฐ๋ณ์๋ก ๊ฐ์ฒด๋ฅผ ๋๊ธธ ๋
๊ฐ์ฒด ์ ์ฒด๋ฅผ ๋ฐ์์ dot(.)์ผ๋ก ์ ๊ทผํ ํ์ ์์ด, ํ์ํ ๋ฐ์ดํฐ๋ง ๋ฐ๋ก ๋ช ์ํ ์ ์์ต๋๋ค.
function printUser({ name, age }) {
console.log(`์ด๋ฆ์ ${name}, ๋์ด๋ ${age}์
๋๋ค.`);
}
const person = { name: "์ด๊ฐ์ธ", age: 23, city: "ํ๋ฆฌ" };
printUser(person); // "์ด๋ฆ์ ์ด๊ฐ์ธ, ๋์ด๋ 23์
๋๋ค."
๐ก๏ธ 3.3.2 ๊ธฐ๋ณธ๊ฐ(Default Value) ์ค์ :
๋ง์ฝ ๊ฐ์ฒด์ ํด๋น ๋ฐ์ดํฐ๊ฐ ์์ ๋ ์ฌ์ฉํ ๊ธฐ๋ณธ๊ฐ์ ์ ํด์ค ์ ์์ต๋๋ค.
const { name, hobby = "์ถ๊ตฌ" } = { name: "๊น๋ฏผ์ฌ" };
console.log(hobby); // ๊ฐ์ฒด์ hobby๊ฐ ์์ผ๋ฏ๋ก ๊ธฐ๋ณธ๊ฐ "์ถ๊ตฌ" ์ถ๋ ฅ
4. ํจ์
4.1. ํจ์ ์ ์ธ๋ฌธ ์ผ๋ก ํจ์ ์์ฑ :
function ํค์๋ ๋ค์ ๋ฐ๋์ ํจ์ ์ด๋ฆ ์์ฑ. (ํน์ง: ํธ์ด์คํ
์ ์ฉ)
sayHello(); // ์คํ ๊ฐ๋ฅ! (ํธ์ด์คํ
)
function sayHello() {
console.log("์๋
ํ์ธ์!");
}
4.2. ํจ์ ๋ฆฌํฐ๋ด (ํจ์ ํํ์, Function Expression)
ํจ์๋ฅผ ๋ณ์์ ๊ฐ์ฒ๋ผ ํ ๋นํ๋ ๋ฐฉ์. (ํน์ง: ํธ์ด์คํ
์ด ๋ฐ์ํ์ง ์์)
// sayHi(); // ์๋ฌ ๋ฐ์!
const sayHi = function() {
console.log("๋ฐ๊ฐ์ต๋๋ค!");
};
sayHi(); // ์ ์ธ ์ดํ์๋ง ํธ์ถ ๊ฐ๋ฅ
4.3. ํ์ดํ ํจ์
4.3.1. ํจ์ ํํ์์ ์ฐจ์ด
4.3.1.1 ๐ฆ ๊ธฐ์กด ๋ฐฉ์ (ํจ์ ํํ์)
const add = function(a, b) {
return a + b;
};
4.3.1.2 ๐ ํ์ดํ ํจ์
const add = (a, b) => {
return a + b;
};
// ์ธ์๊ฐ ํ๋๋ฉด () ์๋ต ๊ฐ๋ฅ
const add1 = a => { return a + 1; };
// ์ธ์๊ฐ ์์ ๋ () ์๋ต ๋ถ๊ฐ
const add2 = () => { return 1 + 2; };
// ํจ์ ์์ ๋ฌธ์ฅ์ด return ๋ฟ์ผ ๋๋ ์ค๊ดํธ์ return ์๋ต ๊ฐ๋ฅ
const add3 = a => a + 1;
// ํจ์ ์์ ๋ฌธ์ฅ์ด return ๋ฟ์ผ ๋๋ ๋ฐํ๊ฐ์ด ๊ฐ์ฒด ๋ฆฌํฐ๋ด์ด๋ฉด ๊ดํธ()๋ก ๋ฌถ์ด์ผ ํจ
const f = (a, b) => ({ x: a, y: b });
๐ 4.3.2. ๋ด๋ถ ๋์์ ์ง์ง ์ฐจ์ด: this์ ๊ฒฐ์ ๋ฐฉ์ (ํต์ฌ ๐)
4.3.2.1 ๐ฆ ๊ธฐ์กด ํจ์์ this: "๋๊ฐ ๋๋ฅผ ๋ถ๋ ์ด?" (๋์ ๋ฐ์ธ๋ฉ) ๊ธฐ์กด ํจ์์์ this๋ ํจ์๊ฐ '์คํ๋ ๋' ๋๊ฐ ์์ ์ ํธ์ถํ๋์ง์ ๋ฐ๋ผ ์์๊ฐ๊ฐ ๋ณํฉ๋๋ค.
const user = {
name: "ํ๊ธธ๋",
sayHi: function() {
console.log(this.name); // ์ ์ ์ถ๋ ฅ: ํ๊ธธ๋
// ๐จ ๋ฌธ์ ๋ฐ์: 1์ด ๋ค์ ์ธ์ฌํ๋ ํจ์๋ฅผ ๋ด๋ถ์ ๋ง๋ฆ
setTimeout(function() {
// ์ด ๋ด๋ถ ํจ์๋ ๋ธ๋ผ์ฐ์ (window)๊ฐ ๋ถ๋ฅธ ๊ฒ์ผ๋ก ์ณ์ this๋ฅผ ์์ด๋ฒ๋ฆฝ๋๋ค.
console.log(`1์ด ๋ค: ์๋
, ๋ ${this.name}์ด์ผ`);
}, 1000);
}
};
user.sayHi();
// ์ถ๋ ฅ: ํ๊ธธ๋
// 1์ด ๋ค ์ถ๋ ฅ: ์๋
, ๋ undefined์ด์ผ <-- ๐ฅ ์๋ฌ ๋ฐ์! this๋ฅผ ์์ด๋ฒ๋ฆผ!
4.3.2.2 ๐ ํ์ดํ ํจ์์ this: "๋ด๊ฐ ํ์ด๋ ๊ณ ํฅ์ด ์ด๋์ผ?" (์ดํ์ ๋ฐ์ธ๋ฉ) ํ์ดํ ํจ์๋ ์์ ์ด ๋ง๋ค์ด์ง ๋ฐ๊นฅ ํ๊ฒฝ(๊ณ ํฅ)์ this๋ฅผ ๊ทธ๋๋ก ๊ฐ์ ธ๋ค ์๋๋ค.
const user = {
name: "ํ๊ธธ๋",
sayHi: function() {
console.log(this.name); // ์ ์ ์ถ๋ ฅ: ํ๊ธธ๋
// โ
ํด๊ฒฐ: ํ์ดํ ํจ์ ์ฌ์ฉ
setTimeout(() => {
// ํ์ดํ ํจ์๋ ๋ฐ๊นฅ์ชฝ์ธ sayHi์ this(user)๋ฅผ ๊ทธ๋๋ก ๋ฌผ๋ ค๋ฐ์ต๋๋ค.
console.log(`1์ด ๋ค: ์๋
, ๋ ${this.name}์ด์ผ`);
}, 1000);
}
};
user.sayHi();
// ์ถ๋ ฅ: ํ๊ธธ๋
// 1์ด ๋ค ์ถ๋ ฅ: ์๋
, ๋ ํ๊ธธ๋์ด์ผ <-- ๐ ์๋ฒฝํ๊ฒ ์๋!
๐ ๏ธ 4.3.3 ํ์ดํ ํจ์์ ํ์ฉ
๐ฆ ์ํฉ ์ค์ : ์๋ฒ์์ ๋ฐ์์จ ๊ณ ๊ฐ ๋ฐ์ดํฐ (Raw Data)
const users = [
{ id: 1, name: "ํ๊ธธ๋", age: 25, isVip: true },
{ id: 2, name: "์ด์์ ", age: 40, isVip: false },
{ id: 3, name: "์ ๊ด์", age: 18, isVip: true },
{ id: 4, name: "๊ฐ๊ฐ์ฐฌ", age: 35, isVip: false }
];
1. map: "๋ฐ์ดํฐ ๊ฐ๊ณต ๊ณต์ฅ" (ํํ ๋ฐ๊พธ๊ธฐ)
// users ๋ฐฐ์ด์ ๋๋ฉด์, ๊ฐ ์ ์ (u)์ ์ด๋ฆ(u.name)๋ง ๋ฝ์ ์๋ก์ด ๋ฐฐ์ด๋ก ๋ง๋ญ๋๋ค.
const names = users.map(u => u.name);
console.log(names);
// ์ถ๋ ฅ: ["ํ๊ธธ๋", "์ด์์ ", "์ ๊ด์", "๊ฐ๊ฐ์ฐฌ"]
2. filter: "๋ฐ์ดํฐ ๊ฑฐ๋ฆ๋ง" (์กฐ๊ฑด์ ๋ง๋ ๊ฒ๋ง ์ถ๋ ค๋ด๊ธฐ)
// users ๋ฐฐ์ด์ ๋๋ฉด์, isVip๊ฐ true์ธ ์ ์ ๋ง ํต๊ณผ์ํต๋๋ค.
const vipUsers = users.filter(u => u.isVip === true);
console.log(vipUsers);
/* ์ถ๋ ฅ:
[
{ id: 1, name: 'ํ๊ธธ๋', age: 25, isVip: true },
{ id: 3, name: '์ ๊ด์', age: 18, isVip: true }
]
*/
๐ 3. ์ค๋ฌด ๋ํ์: ์ฒด์ด๋
const vipNames = users
.filter(u => u.isVip) // 1๋จ๊ณ: VIP๋ง ๋จผ์ ๊ฑธ๋ฌ๋
.map(u => u.name); // 2๋จ๊ณ: ๋จ์ ๋ฐ์ดํฐ์์ ์ด๋ฆ๋ง ๋ฝ์๋
console.log(vipNames);
// ์ถ๋ ฅ: ["ํ๊ธธ๋", "์ ๊ด์"]
4.4. ๋๋จธ์ง ๋งค๊ฐ๋ณ์(Rest Parameter) :
์ ํด์ง์ง ์์ ์์ ์ธ์๋ฅผ ํ๋์ ๋ฐฐ์ด๋ก ๋ชจ์์ฃผ๋ ๋ฌธ๋ฒ
4.4.1. ๊ธฐ๋ณธ ์์ : ํจ์์ ์ธ์๋ฅผ ๋ฐฐ์ด๋ก ๋ฐ๊ธฐ
function sumAll(...numbers) {
// numbers๋ [1, 2, 3, 4, 5] ๋ผ๋ ๋ฐฐ์ด์ด ๋ฉ๋๋ค.
return numbers.reduce((acc, curr) => acc + curr, 0);
}
console.log(sumAll(1, 2)); // 3
console.log(sumAll(1, 2, 3, 4, 5)); // 15
4.4.2. ์ผ๋ฐ ๋งค๊ฐ๋ณ์์ ํจ๊ป ์ฐ๊ธฐ (ํญ์ ๋ง์ง๋ง์ ์์นํด์ผ ํจ)
function showGrade(name, ...scores) {
console.log(`${name}๋์ ์ ์ ๊ฐ์: ${scores.length}๊ฐ`);
console.log(scores); // [90, 85, 100]
}
showGrade("์ฒ ์", 90, 85, 100);
4.4.3. ๊ตฌ์กฐ ๋ถํด ํ ๋น์์์ Rest
// โ ๋ฐฐ์ด์์์ ํ์ฉ
const [first, ...others] = [1, 2, 3, 4, 5];
console.log(first); // 1
console.log(others); // [2, 3, 4, 5]
// โก ๊ฐ์ฒด์์์ ํ์ฉ
const user = { id: 1, name: "์ํฌ", age: 20, city: "์์ธ" };
const { id, ...userInfo } = user;
console.log(id); // 1
console.log(userInfo); // { name: "์ํฌ", age: 20, city: "์์ธ" }
4.5 ์ ๊ฐ ๊ตฌ๋ฌธ (Spread) :
๋ฐฐ์ด์ด๋ ๊ฐ์ฒด๋ผ๋ '์ฃผ๋จธ๋'๋ฅผ ํ์ด์ ๊ทธ ์์ ๋ด์ฉ๋ฌผ์ ํ๋ํ๋ ๋ฑ๊ฐ๋ก ํผ์น๋ ์ญํ
4.5.1. ๋ฐฐ์ด์์์ ์ ๊ฐ ๊ตฌ๋ฌธ
const parts = ["์ด๊นจ", "๋ฌด๋ฆ"];
const body = ["๋จธ๋ฆฌ", ...parts, "๋ฐ"];
console.log(body); // ["๋จธ๋ฆฌ", "์ด๊นจ", "๋ฌด๋ฆ", "๋ฐ"]
// ๋ฐฐ์ด ๋ณต์ฌ (์์ ํ ์๋ก์ด ๋ฐฐ์ด ์์ฑ)
const original = [1, 2, 3];
const copy = [...original];
4.5.2. ๊ฐ์ฒด์์์ ์ ๊ฐ ๊ตฌ๋ฌธ
const user = { name: "์ฒ ์", age: 20 };
const updatedUser = { ...user, city: "์์ธ" };
console.log(updatedUser); // { name: "์ฒ ์", age: 20, city: "์์ธ" }
4.5.3. Rest(๋ชจ์ผ๊ธฐ) vs Spread(ํผ์น๊ธฐ) ๊ตฌ๋ถํ๊ธฐ
๋ชจ์์ ...์ผ๋ก ๋๊ฐ์ง๋ง, ์ฐ์์๋ ์ ๋ฐ๋์.
* Rest: ์ฌ๋ฌ ๊ฐ์ ์ธ์๋ฅผ ๋ฐ์์ ํ๋์ ๋ฐฐ์ด๋ก ๋ง๋ญ๋๋ค. (ํจ์ ํ๋ผ๋ฏธํฐ ์์ญ)
* Spread: ํ๋์ ๋ฐฐ์ด/๊ฐ์ฒด๋ฅผ ์ฌ๋ฌ ๊ฐ์ ๊ฐ์ผ๋ก ์ชผ๊ฐ์ ๋ฃ์ต๋๋ค. (ํจ์ ํธ์ถ์ด๋ ์ ์ธ ๋ฐ)
4.6 ์์ ๋ณต์ฌ(Shallow Copy)์ ๊น์ ๋ณต์ฌ(Deep Copy)
๐ 4.6.1. ์์ ๋ณต์ฌ (Shallow Copy)
๊ฐ์ฒด์ ์ต์์ ๋ ๋ฒจ๋ง ๋ณต์ฌํ๊ณ , ๋ด๋ถ์ ์ค์ฒฉ๋ ๊ฐ์ฒด๋ค์ ์ฐธ์กฐ๊ฐ(์ฃผ์)๋ง ๋ณต์ฌ.
const original = {
name: "์ฒ ์",
skills: ["JS", "HTML"] // ์ค์ฒฉ๋ ๋ฐฐ์ด(๊ฐ์ฒด)
};
const copy = { ...original }; // ์์ ๋ณต์ฌ
copy.name = "์ํฌ"; // 1๋จ๊ณ ๊ฐ ๋ณ๊ฒฝ
copy.skills.push("CSS"); // 2๋จ๊ณ(์ค์ฒฉ ๊ฐ์ฒด) ๊ฐ ๋ณ๊ฒฝ
console.log(original.name); // "์ฒ ์" (1๋จ๊ณ๋ ์ํฅ ์์)
console.log(original.skills); // ["JS", "HTML", "CSS"] (์๋ณธ๋ ๊ฐ์ด ๋ฐ๋!)
๐ 4.6.2. ๊น์ ๋ณต์ฌ (Deep Copy)
๊ฐ์ฒด์ ๋ชจ๋ ๋ ๋ฒจ์ ์์ ํ ์๋ก์ด ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์ ๋ณต์ฌ. (์๋ณธ๊ณผ ๋ณต์ฌ๋ณธ ์๋ฒฝ ๋ถ๋ฆฌ)
const original = {
name: "์ฒ ์",
skills: ["JS", "HTML"]
};
// ์ต์ ๋ธ๋ผ์ฐ์ ํ์ค ๋ฐฉ์ (์ถ์ฒ) structuredClone ์ฌ์ฉ
const deepCopy = structuredClone(original);
deepCopy.skills.push("React");
console.log(original.skills); // ["JS", "HTML"] (์๋ณธ ๋ณด์กด!)
console.log(deepCopy.skills); // ["JS", "HTML", "React"] (๋ณต์ฌ๋ณธ๋ง ๋ณ๊ฒฝ)
4.7 ํด๋ก์ (์ฐธ๊ณ ) :
๐ ํจ์๊ฐ ์์ ์ด ํ์ด๋ ๊ณ ํฅ์ ํ๊ฒฝ(๋ณ์๋ค)์ ๊ธฐ์ตํ๋ '๋ฐฐ๋ญ'์ ๋ฉ๊ณ ๋ค๋๋ ๊ฒ
4.7.1. ํด๋ก์ ๊ฐ ์๋ ํ๋ฒํ ์ธ๊ณ
function sayHello() {
let name = "ํ๊ธธ๋"; // ํจ์ ์์์ ๋ณ์ ์์ฑ
console.log(name);
}
sayHello(); // "ํ๊ธธ๋" ์ถ๋ ฅ
// ์ด ์์ ์์ ํจ์ ์คํ์ด ๋๋ฌ์ผ๋ฏ๋ก, name์ด๋ผ๋ ๋ณ์๋ ์์ ํ ํ๊ดด๋ฉ๋๋ค.
4.7.2. ๐ ํจ์ ์์ ๋ ๋ค๋ฅธ ํจ์(๋ด๋ถ ํจ์)๋ฅผ ๋ง๋ค์ด์ ๋ฐ์ผ๋ก ๋ด๋ณด๋ด๋ฉด ๋ณ์ ์ ์ง
function makeCounter() {
let count = 0; // 1. ๊ณ ํฅ(์ธ๋ถ ํจ์)์ ๋ณ์
// 2. ๋ด๋ถ ํจ์๋ฅผ ๋ง๋ค์ด์ ๋ฐ์ผ๋ก ๋ฐํ(return)ํฉ๋๋ค.
return function() {
count = count + 1; // 3. ๊ณ ํฅ์ ๋ณ์์ธ count๋ฅผ ์ฌ์ฉํฉ๋๋ค.
return count;
};
}
const myCounter = makeCounter();
// makeCounter()์ ์คํ์ ๋๋ฌ๊ณ count ๋ณ์๋ ํ๊ดด๋์ด์ผ ํ์ง๋ง, ๊ณ์ ์๋ํฉ๋๋ค!
console.log(myCounter()); // ์ถ๋ ฅ: 1
console.log(myCounter()); // ์ถ๋ ฅ: 2
console.log(myCounter()); // ์ถ๋ ฅ: 3
5. ํด๋์ค
5.1. ES5: ์์ฑ์ ํจ์(Constructor)์ new ์ฐ์ฐ์
โ๏ธ 5.1.1. ๋์ ์๋ฆฌ:
function Person(name, age) {
this.name = name;
this.age = age;
}
// ๋ฉ์๋๋ prototype์ ๋ช
์์ ์ผ๋ก ์ถ๊ฐ
Person.prototype.sayHello = function() {
console.log("์๋
ํ์ธ์, ์ ์ด๋ฆ์ " + this.name + "์
๋๋ค.");
};
// new๋ฅผ ์ฌ์ฉํด ์ธ์คํด์ค ์์ฑ
var user1 = new Person("๊น์ฒ ์", 25);
user1.sayHello(); // ์ถ๋ ฅ: ์๋
ํ์ธ์, ์ ์ด๋ฆ์ ๊น์ฒ ์์
๋๋ค.
5.2. ES6: class ํค์๋ ๋์
๐ 5.2.1. ๋์ ์๋ฆฌ:
class Person {
// [์์ 2: ์์ฑ] ์ธ๋ถ์ ์ ๋ ๊ณต๊ฐํ๋ฉด ์ ๋๋ ๋ฐ์ดํฐ (ํ๋ผ์ด๋น ํ๋)
#name;
// [์์ 1: ์์ฑ์] ์์ฑ ์ด๊ธฐํ
constructor(name) {
// ์ด๊ฑด this.#name ๋ณ์์ ์ง์ ๊ฐ์ ํ ๋นํ๋๊ฒ ์๋๋ผ setter ๋ฅผ ํธ์ถํด์ฃผ๋ ๊ฒ์
this.name = name;
}
// [์์ 4: Getter]
get name() {
return this.#name;
}
// [์์ 4: Setter] ์ธ๋ถ์์ ์ด๋ฆ์ ๋ฐ๊พธ๊ฒ ํ๊ณ ์ถ๋ค๋ฉด setter๋ฅผ ์ถ๊ฐ
set name(value) {
this.#name = value;
}
// [์์ 3: ๋ฉ์๋] ๋ฉ์๋๋ prototype์ ์๋์ผ๋ก ์ถ๊ฐ๋จ.
sayHello() {
// ์ฌ๊ธฐ์ this.name์ ์ฐ๋ฉด ์๋์ผ๋ก Getter๋ฅผ ํธ์ถํด์ ๊ฐ์ ๊ฐ์ ธ์ด
console.log(`์๋
ํ์ธ์, ์ ์ด๋ฆ์ ${this.name}์
๋๋ค.`);
}
}
// ์ธ์คํด์ค ์์ฑ ๋ฐฉ์์ ๋์ผ
const user = new Person("์ด์ํฌ");
user.sayHello(); // ์ถ๋ ฅ: ์๋
ํ์ธ์, ์ ์ด๋ฆ์ ์ด์ํฌ์
๋๋ค.
// setter ํธ์ถ
user.name = "์ฒ ์";
// getter ํธ์ถ
console.log(user.name); // ์ถ๋ ฅ : ์ฒ ์
// ํ๋ผ์ด๋น ํ๋ ์ง์ ์ ๊ทผ ์๋ (ํด๋์ค ๋ฐ์์๋ ๋ถ๊ฐ)
// console.log(user.#name); // ๐ฅ ์๋ฌ ๋ฐ์!
6. ๋ชจ๋
6.1. Named Export & Import (์ด๋ฆ์ ์ง์ ํด์ ์ฌ๋ฌ ๊ฐ ๋ด๋ณด๋ด๊ธฐ/๊ฐ์ ธ์ค๊ธฐ)
๐งฉ ํ ํ์ผ์์ ์ฌ๋ฌ ๊ฐ์ ํจ์, ๋ณ์๋ฅผ ๋ด๋ณด๋ผ ๋ ์ฌ์ฉ. ๋ฐ๋์ ์ค๊ดํธ { } ๋ฅผ ์ฌ์ฉํด ์๋ ์ด๋ฆ ๊ทธ๋๋ก ๊ฐ์ ธ์์ผ ํฉ๋๋ค.
[math.js] - ๋ถํ(๋ชจ๋)์ ๋ง๋๋ ํ์ผ
// ์ ์ธ๋ถ ์์ export๋ฅผ ๋ถ์ฌ์ ์ธ๋ถ๋ก ๋ด๋ณด๋
๋๋ค.
export const PI = 3.141592;
export function add(a, b) {
return a + b;
}
export const multiply = (a, b) => a * b;
// ๐ก (์ฐธ๊ณ ) ํ์ผ ๋งจ ์๋์์ ํ ๋ฒ์ ๋ฌถ์ด์ ๋ด๋ณด๋ผ ์๋ ์์ต๋๋ค.
// export { PI, add, multiply };
[app.js] - ๋ถํ์ ๊ฐ์ ธ์์ ์ฌ์ฉํ๋ ํ์ผ
// ๊ตฌ์กฐ ๋ถํด ํ ๋น์ฒ๋ผ ํ์ํ ๊ฒ๋ง ์ค๊ดํธ {} ๋ก ๋ฌถ์ด์ ๊ฐ์ ธ์ต๋๋ค.
import { PI, add } from './math.js';
console.log(PI); // 3.141592
console.log(add(10, 20)); // 30
// ๐ก ๋ง์ฝ ๊ฐ์ ธ์ฌ ๋ ์ด๋ฆ์ ๋ฐ๊พธ๊ณ ์ถ๋ค๋ฉด 'as' ํค์๋๋ฅผ ์ฌ์ฉํฉ๋๋ค.
import { multiply as multi } from './math.js';
console.log(multi(2, 5)); // 10
6.2. Default Export & Import (ํ์ผ์ ์ฃผ์ธ๊ณต ๋ฑ 1๊ฐ๋ง ๋ด๋ณด๋ด๊ธฐ/๊ฐ์ ธ์ค๊ธฐ)
๐ ํ ํ์ผ์ ๋ฉ์ธ์ด ๋๋ ํด๋์ค๋ ํจ์๊ฐ ํ๋๋ง ์์ ๋ ์ฌ์ฉ. ์ค๊ดํธ { } ์์ด, ์ํ๋ ์ด๋ฆ์ผ๋ก ๋ง์๋๋ก ์ง์ด์ ๊ฐ์ ธ์ฌ ์ ์์ต๋๋ค.
[User.js] - ๋ถํ์ ๋ง๋๋ ํ์ผ
class User {
constructor(name) {
this.name = name;
}
greet() {
console.log(`์๋
ํ์ธ์, ${this.name}์
๋๋ค.`);
}
}
// ์ด ํ์ผ์ ๋ํ(default) ๋ชจ๋๋ก User ํด๋์ค๋ฅผ ์ง์ ํฉ๋๋ค.
export default User;
[main.js] - ๋ถํ์ ๊ฐ์ ธ์์ ์ฌ์ฉํ๋ ํ์ผ
// default๋ก ๋ด๋ณด๋ธ ๋ชจ๋์ ๊ดํธ ์์ด ์์ ๋ก์ด ์ด๋ฆ์ผ๋ก ๊ฐ์ ธ์ฌ ์ ์์ต๋๋ค.
import Customer from './User.js'; // User๋ฅผ Customer๋ผ๋ ์ด๋ฆ์ผ๋ก ๋ฐ์
const user1 = new Customer("ํ๊ธธ๋");
user1.greet(); // ์๋
ํ์ธ์, ํ๊ธธ๋์
๋๋ค.
6.3. * (์์ผ๋์นด๋)๋ฅผ ์ฌ์ฉํด ํ ๋ฒ์ ๋ชฝ๋
๊ฐ์ ธ์ค๊ธฐ
๐ฆ ๋ด๋ณด๋ธ ๋ชจ๋์ด ๋๋ฌด ๋ง์์ ์ผ์ผ์ด ์ ๊ธฐ ๊ท์ฐฎ์ ๋, ํ์ผ ์์ฒด๋ฅผ ํ๋์ ๊ฐ์ฒด๋ก ํต์งธ๋ก ๋ถ๋ฌ์ต๋๋ค.
[app.js]
// math.js์ ๋ชจ๋ export๋ฅผ ๊ฐ์ ธ์์ 'MathUtils'๋ผ๋ ํ๋์ ๊ฐ์ฒด ์์ ๋ด์ต๋๋ค.
import * as MathUtils from './math.js';
// ๊ฐ์ฒด์ ํ๋กํผํฐ(์ ํ๊ธฐ๋ฒ)๋ฅผ ํตํด ์ ๊ทผํฉ๋๋ค.
console.log(MathUtils.PI);
console.log(MathUtils.add(5, 5));
6.4. HTML์์ ๋ชจ๋ ์ฐ๊ฒฐํ๊ธฐ (ํต์ฌ ์ฃผ์์ฌํญ ๐จ)
๐ ๋ธ๋ผ์ฐ์ (HTML) ํ๊ฒฝ์์ import / export๋ฅผ ์ฐ๋ ค๋ฉด script ํ๊ทธ์ ๋ฐ๋์ type="module" ์์ฑ์ ์ ์ด์ค์ผ ํฉ๋๋ค.
[index.html]
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>๋ชจ๋ ํ
์คํธ</title>
</head>
<body>
<script type="module" src="app.js"></script>
</body>
</html>
7. Promise
7.1. Promise์ 3๊ฐ์ง ์ํ (State)
๐ฆ Promise๋ ์์
์ด ๋๋ ๋๊น์ง ๊ฒฐ๊ณผ๋ฅผ '์ฝ์'ํ๋ ๊ฐ์ฒด์
๋๋ค. ํ์ฌ ์์
์ด ์ด๋ค ์ํ์ธ์ง 3๊ฐ์ง๋ก ๋๋ฉ๋๋ค.
- Pending (๋๊ธฐ): ๋น๋๊ธฐ ์ฒ๋ฆฌ๊ฐ ์์ง ๋๋์ง ์์ ์ํ (์ฝ์์ ํ์ง๋ง ์์ง ๊ฒฐ๊ณผ๊ฐ ์ ๋์ด)
- Fulfilled (์ดํ/์ฑ๊ณต): ๋น๋๊ธฐ ์ฒ๋ฆฌ๊ฐ ์ฑ๊ณต์ ์ผ๋ก ์๋ฃ๋์ด ์ฝ์ํ ๊ฒฐ๊ณผ๊ฐ์ ๋ฐํํ ์ํ
- Rejected (๊ฑฐ๋ถ/์คํจ): ๋น๋๊ธฐ ์ฒ๋ฆฌ๊ฐ ์คํจํ๊ฑฐ๋ ์ค๋ฅ๊ฐ ๋ฐ์ํ ์ํ
7.2. Promise ๋ง๋ค๊ธฐ (์์ฐ์ - Producer)
๐ ๏ธ new Promise๋ฅผ ํตํด ์์ฑํ๋ฉฐ, ์์ resolve(์ฑ๊ณต ์ ํธ์ถ)์ reject(์คํจ ์ ํธ์ถ)๋ผ๋ ๋ ๊ฐ์ง ์ฝ๋ฐฑ ํจ์๋ฅผ ๋ฐ์ต๋๋ค.
// ์๋ฒ์์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ์ํฉ์ ๊ฐ์ ํด๋ด
๋๋ค.
const fetchData = new Promise((resolve, reject) => {
console.log("๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ์ค...");
setTimeout(() => {
const success = true; // ํต์ ์ฑ๊ณต ์ฌ๋ถ (ํ
์คํธ์ฉ)
if (success) {
// 1. ์ฑ๊ณตํ์ ๋: resolve() ์์ ๊ฒฐ๊ณผ ๋ฐ์ดํฐ๋ฅผ ๋ด์์ ๋ณด๋
๋๋ค. (์ํ: Fulfilled)
resolve({ id: 1, name: "ํ๊ธธ๋" });
} else {
// 2. ์คํจํ์ ๋: reject() ์์ ์๋ฌ ๊ฐ์ฒด๋ฅผ ๋ด์์ ๋ณด๋
๋๋ค. (์ํ: Rejected)
reject(new Error("๋คํธ์ํฌ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค."));
}
}, 2000); // 2์ด ๊ฑธ๋ฆฌ๋ ์์
์ด๋ผ๊ณ ๊ฐ์
});
7.3. Promise ์ฌ์ฉํ๊ธฐ (์๋น์ - Consumer)
๐ง ๋ง๋ค์ด์ง Promise๋ .then()์ผ๋ก ์ฑ๊ณต์, .catch()๋ก ์คํจ๋ฅผ, .finally()๋ก ๋ฌด์กฐ๊ฑด ์คํํ ์ฝ๋๋ฅผ ๋ฐ์ต๋๋ค.
// ์์์ ๋ง๋ fetchData(Promise ๊ฐ์ฒด)๋ฅผ ์ฌ์ฉํด๋ด
์๋ค.
fetchData
.then((data) => {
// 1. resolve()๊ฐ ํธ์ถ๋๋ฉด ์ฌ๊ธฐ๊ฐ ์คํ๋ฉ๋๋ค.
console.log("โ
์ฑ๊ณต:", data); // ์ถ๋ ฅ: โ
์ฑ๊ณต: { id: 1, name: 'ํ๊ธธ๋' }
})
.catch((error) => {
// 2. reject()๊ฐ ํธ์ถ๋๋ฉด ์ฌ๊ธฐ๊ฐ ์คํ๋ฉ๋๋ค. (์๋ฌ ์ฒ๋ฆฌ)
console.log("โ ์คํจ:", error.message);
})
.finally(() => {
// 3. ์ฑ๊ณตํ๋ ์คํจํ๋ ๋ง์ง๋ง์ ๋ฌด์กฐ๊ฑด ํ ๋ฒ ์คํ๋ฉ๋๋ค. (๋ก๋ฉ ์คํผ๋ ๋ ๋ ์ฃผ๋ก ์ฌ์ฉ)
console.log("๐ ๋ชจ๋ ์์
์ด ๋๋ฌ์ต๋๋ค.");
});
7.4. ์ค๋ฌด์ ๊ฝ: Promise ์ฒด์ด๋ (Chaining)
โ๏ธ ๊ณผ๊ฑฐ์๋ ์ฝ๋ฐฑ ํจ์ ์์ ์ฝ๋ฐฑ ํจ์๋ฅผ ๋ฃ๋ '์ฝ๋ฐฑ ์ง์ฅ(Callback Hell)'์ด ์์์ง๋ง, Promise๋ .then()์ ๊ธฐ์ฐจ์ฒ๋ผ ์ฐ๊ฒฐํด์ ๊น๋ํ๊ฒ ์ฒ๋ฆฌํฉ๋๋ค.
// ์๋ฒ์์ ๋ฒํธ๋ฅผ ๊ฐ์ ธ์ค๊ณ -> ๊ทธ ๋ฒํธ๋ก ์ฌ์ฉ์๋ฅผ ์ฐพ๊ณ -> ๊ทธ ์ฌ์ฉ์์ ๊ฒ์๊ธ์ ์ฐพ๋ ์ฐ์๋ ์์
const fetchNumber = new Promise((resolve) => {
setTimeout(() => resolve(1), 1000);
});
fetchNumber
.then(num => {
console.log(`์ฒซ ๋ฒ์งธ ๊ฒฐ๊ณผ: ${num}`); // 1
return num * 10; // return ํ๋ฉด ์ด ๊ฐ์ด ๋ค์ .then()์ผ๋ก ๋์ด๊ฐ๋๋ค. (์๋์ผ๋ก ์๋ก์ด Promise๊ฐ ๋จ)
})
.then(num => {
console.log(`๋ ๋ฒ์งธ ๊ฒฐ๊ณผ: ${num}`); // 10
return num * 10;
})
.then(num => {
console.log(`์ธ ๋ฒ์งธ ๊ฒฐ๊ณผ: ${num}`); // 100
})
.catch(error => {
// ์ค๊ฐ์ ์ด๋์๋ ์๋ฌ๊ฐ ํฐ์ง๋ฉด, ๊ฐ์ฅ ๊ฐ๊น์ด catch ํ๋๊ฐ ๋ชจ๋ ์ก์๋
๋๋ค.
console.log("์๋ฌ ๋ฐ์!", error);
});
7.5. ์ค๋ฌด์์ ๊ฐ์ฅ ๋ง์ด ์ฐ๋ Promise ๋ฉ์๋ ๋ชจ์
๐ฆ ์ฌ๋ฌ ๊ฐ์ ๋น๋๊ธฐ ์์
์ ๋์์ ๋ฌถ์ด์ ์ฒ๋ฆฌํ ๋ ์ ์ฉํ ๋ฉ์๋๋ค์
๋๋ค.
const p1 = new Promise(resolve => setTimeout(() => resolve("1๋ฒ ๋ฐ์ดํฐ"), 1000));
const p2 = new Promise(resolve => setTimeout(() => resolve("2๋ฒ ๋ฐ์ดํฐ"), 2000));
// 1. Promise.all()
// ๋ชจ๋ ์ฝ์์ด '์ฑ๊ณต'ํ ๋๊น์ง ๊ธฐ๋ค๋ ธ๋ค๊ฐ, ํ ๋ฒ์ ๋ฐฐ์ด๋ก ๊ฒฐ๊ณผ๋ฅผ ๋ฐ์ต๋๋ค.
// (๋จ, ํ๋๋ผ๋ ์คํจํ๋ฉด ์ ์ฒด๊ฐ ์ฆ์ catch๋ก ๋น ์ ธ๋ฒ๋ฆผ)
Promise.all([p1, p2])
.then(results => console.log("๋ชจ๋ ์๋ฃ:", results));
// 2์ด ๋ค ์ถ๋ ฅ: ๋ชจ๋ ์๋ฃ: ["1๋ฒ ๋ฐ์ดํฐ", "2๋ฒ ๋ฐ์ดํฐ"]
// 2. Promise.race()
// ๋ฌ๋ฆฌ๊ธฐ ๊ฒฝ์ฃผ์ฒ๋ผ ์ฌ๋ฌ ์์
์ค '๊ฐ์ฅ ๋จผ์ ๋๋ ๊ฒ' ํ๋์ ๊ฒฐ๊ณผ๋ง ๊ฐ์ ธ์ต๋๋ค.
Promise.race([p1, p2])
.then(result => console.log("1๋ฑ:", result));
// 1์ด ๋ค ์ถ๋ ฅ: 1๋ฑ: 1๋ฒ ๋ฐ์ดํฐ
7.6. Promise.allSettled() (์ฌ๋ฌ ํ๋ก๋ฏธ์ค์ ๊ฒฐ๊ณผ๋ฅผ ๋ชจ๋ ๋ฐฐ์ด๋ก ๋ฐํ)
๐ก๏ธ Promise.all()์ ๋จ์ (ํ๋๋ผ๋ ์คํจํ๋ฉด ๋ฉ์ถค)์ ๋ณด์ํ์ฌ, ์ฑ๊ณต/์คํจ ์ฌ๋ถ์ ์๊ด์์ด ๋ชจ๋ ๊ฒฐ๊ณผ๋ฅผ ๋๊น์ง ๊ธฐ๋ค๋ฆฐ ํ ์ํ์ ํจ๊ป ๋ฐฐ์ด๋ก ๋ฐํํฉ๋๋ค. (ES11 ๋์
/ ์ค๋ฌด ์ถ์ฒ๐)
const p1 = new Promise(resolve => setTimeout(() => resolve("์ฑ๊ณต ๋ฐ์ดํฐ"), 1000));
const p2 = new Promise((_, reject) => setTimeout(() => reject("์คํจ ์๋ฌ"), 2000));
Promise.allSettled([p1, p2])
.then(results => console.log(results));
/*
์ถ๋ ฅ ๊ฒฐ๊ณผ (2์ด ๋ค ๋ฐฐ์ด ๋ฐํ):
[
{ status: "fulfilled", value: "์ฑ๊ณต ๋ฐ์ดํฐ" },
{ status: "rejected", reason: "์คํจ ์๋ฌ" }
]
*/
8. async / await
8.1. async์ await์ ๊ธฐ๋ณธ ๊ท์น
๐ก ์ด ๋ ๊ฐ์ง ํค์๋๋ง ๊ธฐ์ตํ๋ฉด ๋น๋๊ธฐ ์ฝ๋๊ฐ ๊ฑฐ์ง๋ง์ฒ๋ผ ์ฌ์์ง๋๋ค.
async: ํจ์ ์์ ๋ถ์ด๋ฉด, ๊ทธ ํจ์๋ ๋ฌด์กฐ๊ฑด Promise ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ ํจ์๋ก ๋ณ์ ํฉ๋๋ค.await: ๋ฐ๋์asyncํจ์ ์์์๋ง ์ธ ์ ์์ต๋๋ค. Promise ์์ ์ด ๋๋ ๋๊น์ง ์ฝ๋ ์คํ์ '์ ๊น ๋ฉ์ถ๊ณ ๊ธฐ๋ค๋ ค์ฃผ๋(await)' ์ญํ ์ ํฉ๋๋ค. (์ฆ,.then()์ ๋์ฒดํฉ๋๋ค)
8.2. Promise (.then) vs async/await ์ฝ๋ ๋น๊ต
๐ฅ ์ async/await๋ฅผ ์จ์ผ ํ๋์ง ์ฝ๋๋ก ์ง์ ๋น๊ตํด ๋ด
์๋ค. (์๋ฒ์์ ์ฌ์ฉ์ ์ ๋ณด๋ฅผ ๊ฐ์ ธ์ค๋ ์ํฉ)
[๊ธฐ์กด ๋ฐฉ์] Promise ์ฒด์ด๋ (.then ์ฌ์ฉ)
function getUser() {
// fetch()๋ ์๋ฒ์์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ๋ด์ฅ Promise ํจ์์
๋๋ค.
fetch('[https://jsonplaceholder.typicode.com/users/1](https://jsonplaceholder.typicode.com/users/1)')
.then(response => response.json())
.then(user => {
console.log("์ฌ์ฉ์ ์ด๋ฆ:", user.name);
})
.catch(error => {
console.log("์๋ฌ ๋ฐ์:", error);
});
}
[์ต์ ๋ฐฉ์] async / await ์ฌ์ฉ ๐ (์ค๋ฌด ํ์ค)
// ํจ์ ์์ async๋ฅผ ๋ถ์ฌ์ค๋๋ค.
async function getUserAsync() {
// await๋ฅผ ์ฐ๋ฉด ๋ฐ์ดํฐ๊ฐ ์ฌ ๋๊น์ง ๊ธฐ๋ค๋ ธ๋ค๊ฐ, ์ค๋ฉด ์ผ์ชฝ ๋ณ์์ ์ ๋ฃ์ด์ค๋๋ค.
const response = await fetch('[https://jsonplaceholder.typicode.com/users/1](https://jsonplaceholder.typicode.com/users/1)');
const user = await response.json();
// ์ฝ๋ฐฑ ํจ์(ํ์ดํ) ์์ด ์์์ ์๋๋ก ๋ฌผ ํ๋ฅด๋ฏ ์ฝํ๋๋ค!
console.log("์ฌ์ฉ์ ์ด๋ฆ:", user.name);
}
getUserAsync();
8.3. ์๋ฌ ์ฒ๋ฆฌํ๊ธฐ (try ... catch)
๐ก๏ธ async/await์์๋ .catch() ๋์ ์๋ฐ์คํฌ๋ฆฝํธ์ ์ ํต์ ์ธ ์๋ฌ ์ฒ๋ฆฌ ๋ฐฉ์์ธ try/catch ๋ฌธ์ ์ฌ์ฉํฉ๋๋ค.
async function getUserSafe() {
try {
// 1. ์คํํ ์ฝ๋๋ฅผ try ์์ ๋ฃ์ต๋๋ค.
const response = await fetch('https://์๋ชป๋_[์ฃผ์.com/users/1](https://์ฃผ์.com/users/1)');
const user = await response.json();
console.log(user);
} catch (error) {
// 2. try ์์์ ์๋ฌ๊ฐ ํฐ์ง๋ฉด ์ฝ๋๊ฐ ๋ฉ์ถ์ง ์๊ณ ์ฆ์ catch๋ก ๋์ด์ต๋๋ค.
console.log("โ ํต์ ์ค ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ต๋๋ค!", error.message);
} finally {
// 3. (์ ํ์ฌํญ) ์ฑ๊ณตํ๋ ์คํจํ๋ ๋ง์ง๋ง์ ์คํ๋ฉ๋๋ค.
console.log("๋ก๋ฉ ํ๋ฉด ์ข
๋ฃ");
}
}
8.4. ์ค๋ฌด ๊ฟํ: Promise.all๊ณผ ํจ๊ป ์ฐ๊ธฐ (๋ณ๋ ฌ ์ฒ๋ฆฌ)
โก await๋ ์ฝ๋๋ฅผ '๊ธฐ๋ค๋ฆฌ๊ฒ' ๋ง๋ญ๋๋ค. ๋ง์ฝ ์๋ก ์ฐ๊ด ์๋ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ฌ ๋ ๋ฌด์์ await๋ง ์ฐ๋ฉด ์๋๊ฐ ๋๋ ค์ง๋๋ค.
๐จ ๋๋ฆฐ ๋ฐฉ์ (์์ฐจ ์ฒ๋ฆฌ)
async function getDashboardData() {
// ๋ ์จ๋ฅผ ๊ฐ์ ธ์ค๋๋ฐ 2์ด ๋๊ธฐ
const weather = await fetch('/api/weather');
// ๊ทธ ๋ค์ ๋ด์ค๋ฅผ ๊ฐ์ ธ์ค๋๋ฐ 2์ด ๋๊ธฐ (์ด 4์ด ์์)
const news = await fetch('/api/news');
}
๐ ๋น ๋ฅธ ๋ฐฉ์ (๋ณ๋ ฌ ์ฒ๋ฆฌ - Promise.all ํ์ฉ)
๋์์ ๊ฐ์ ธ์๋ ๋๋ ๋ฐ์ดํฐ๋ผ๋ฉด Promise.all๊ณผ ๋ฌถ์ด์ ์ฌ์ฉํฉ๋๋ค.
async function getDashboardDataFast() {
// ๋ ์์ฒญ์ ๋์์ ์๊ณ , ๋ ๋ค ๋๋ ๋๊น์ง(await) ํ ๋ฒ๋ง ๊ธฐ๋ค๋ฆฝ๋๋ค. (์ด 2์ด ์์)
const [weather, news] = await Promise.all([
fetch('/api/weather'),
fetch('/api/news')
]);
console.log("๋ฐ์ดํฐ ๋ก๋ฉ ์๋ฃ!");
}
9. ์ต์ ๋ ์ฒด์ด๋
9.1. ๊ณผ๊ฑฐ์ ๊ณ ํต์ค๋ฌ์ด ์๋ฌ ๋ฐฉ์ด ๋ฐฉ์
๐ฃ ๊ฐ์ฒด ์์ ๊ฐ์ฒด๋ฅผ ์ฐพ์ ๋, ์ค๊ฐ์ ๊ฐ์ด ์์ผ๋ฉด(undefined) TypeError๊ฐ ๋ฐ์ํ๋ฉฐ ํ๋ฉด์ด ๋ป์ด๋ฒ๋ฆฝ๋๋ค.
const user = {
name: "ํ๊ธธ๋",
// profile ์ ๋ณด๊ฐ ์์ ์๋ ์ ์ ๋ผ๊ณ ๊ฐ์ ํด๋ด
๋๋ค.
};
// ๐จ [์ํ] ์๋ฌ ๋ฐ์! undefined.address๋ฅผ ์ฝ์ผ๋ ค๊ณ ์๋ํ๊ธฐ ๋๋ฌธ์
๋๋ค.
// console.log(user.profile.address);
// ๐ฆ [๊ณผ๊ฑฐ ES5 ๋ฐฉ์] ์๋ฌ๋ฅผ ๋ง๊ธฐ ์ํด && ์ฐ์ฐ์๋ฅผ ๊ธฐ์ฐจ์ฒ๋ผ ์ฐ๊ฒฐํด์ผ ํ์ต๋๋ค.
if (user && user.profile && user.profile.address) {
console.log(user.profile.address);
} else {
console.log("์ฃผ์ ์ ๋ณด๊ฐ ์์ต๋๋ค.");
}
9.2. ์ต์
๋ ์ฒด์ด๋ (?.)์ ๋์
๐ช ?. ์ ์ฌ์ฉํ๋ฉด ์ค๊ฐ์ ๊ฐ์ด ์์ด๋ ์๋ฌ๋ฅผ ๋ด์ง ์๊ณ ์กฐ์ฉํ undefined๋ฅผ ๋ฐํํ๊ณ ๋ฉ์ถฅ๋๋ค.
const user = { name: "ํ๊ธธ๋" };
// โ
[์ต์ ES11 ๋ฐฉ์]
// "user ์์ profile์ด ํน์ ์๋? (?. ) ์์ผ๋ฉด address๋ ์ฐพ์์ค!"
const address = user?.profile?.address;
console.log(address);
// ์๋ฌ๊ฐ ๋์ง ์๊ณ ์กฐ์ฉํ 'undefined'๋ฅผ ์ถ๋ ฅํฉ๋๋ค.
9.3. ๋ฐฐ์ด๊ณผ ํจ์์์์ ํ์ฉ
๐ฏ ๊ฐ์ฒด์ ์์ฑ๋ฟ๋ง ์๋๋ผ, ๋ฐฐ์ด์ ์ธ๋ฑ์ค๋ ํจ์ ํธ์ถ ์์๋ ์์ ํ๊ฒ ์ ๊ทผํ ์ ์์ต๋๋ค.
// 1. ๋ฐฐ์ด ์์์ ์์ ํ๊ฒ ์ ๊ทผํ๊ธฐ
const users = null;
// users๊ฐ ๋ฐฐ์ด์ด ์๋๊ฑฐ๋ null์ด์ด๋ ์๋ฌ ์์ด undefined ๋ฐํ
console.log(users?.[0]?.name);
// 2. ํจ์(๋ฉ์๋) ์์ ํ๊ฒ ํธ์ถํ๊ธฐ
const admin = {
adminPlay() {
console.log("๊ด๋ฆฌ์ ๋ชจ๋ ์คํ!");
}
};
const guest = {};
// adminPlay๋ผ๋ ํจ์๊ฐ ์กด์ฌํ ๋๋ง ์คํํด๋ผ!
admin.adminPlay?.(); // "๊ด๋ฆฌ์ ๋ชจ๋ ์คํ!"
guest.adminPlay?.(); // ์๋ฌ ์์ด ์กฐ์ฉํ ๋์ด๊ฐ
10. ๋ ๋ณํฉ ์ฐ์ฐ์
10.1. ๊ธฐ์กด OR (||) ์ฐ์ฐ์์ ์น๋ช
์ ์ธ ๋ฒ๊ทธ
๐จ ๊ธฐ์กด์๋ ๊ฐ์ด ์์ ๋ || ๋ฅผ ์จ์ ๊ธฐ๋ณธ๊ฐ์ ๋ฃ์์ง๋ง, ์ซ์ 0์ด๋ ๋น ๋ฌธ์์ด("")๋ '๊ฑฐ์ง(์์)'์ผ๋ก ํ๋จํด๋ฒ๋ฆฌ๋ ์ฌ๊ฐํ ๋ฒ๊ทธ๊ฐ ์์์ต๋๋ค.
// ์ผํ๋ชฐ ์ํ ์ฅ๋ฐ๊ตฌ๋ ์๋์ 0๊ฐ๋ก ์ค์ ํ๋ค๊ณ ๊ฐ์ ํด๋ด
์๋ค.
const count = 0;
// ๊ฐ๋ฐ์์ ์๋: "count ๊ฐ์ด ์์ ์์ผ๋ฉด ๊ธฐ๋ณธ๊ฐ 10์ ๋ฃ์ด์ค!"
const result = count || 10;
console.log(result);
// ์ถ๋ ฅ: 10 (๋ฒ๊ทธ ๋ฐ์๐ฅ)
// ์๋ฐ์คํฌ๋ฆฝํธ๋ ์ซ์ 0์ '๊ฑฐ์ง(false)'์ผ๋ก ์ทจ๊ธํ๊ธฐ ๋๋ฌธ์ ์ฌ์ฉ์๊ฐ ์
๋ ฅํ 0์ ๋ฌด์ํด๋ฒ๋ฆฝ๋๋ค.
10.2. ๋ ๋ณํฉ ์ฐ์ฐ์ (??)์ ์๋ฒฝํ ํด๊ฒฐ์ฑ
๐ก๏ธ ?? ๋ ์ค์ง ๊ฐ์ด 'null' ์ด๊ฑฐ๋ 'undefined' ์ผ ๋๋ง ์ค๋ฅธ์ชฝ์ ๊ธฐ๋ณธ๊ฐ์ ๋ณด์ฌ์ค๋๋ค. ์ซ์ 0์ด๋ ๋น ๋ฌธ์์ด์ ์ด์ฟํ '๊ฐ'์ผ๋ก ์ธ์ ํด์ค๋๋ค.
const count = 0;
const text = "";
// โ
[์ต์ ES11 ๋ฐฉ์]
const safeCount = count ?? 10;
const safeText = text ?? "๊ธฐ๋ณธ ํ
์คํธ";
console.log(safeCount); // ์ถ๋ ฅ: 0 (์ ์ ์๋! 0์ ๊ฐ์ผ๋ก ์ธ์ ํจ)
console.log(safeText); // ์ถ๋ ฅ: "" (์ ์ ์๋! ๋น ๋ฌธ์์ด๋ ๊ฐ์ผ๋ก ์ธ์ ํจ)
// ์ค์ง null ์ด๋ undefined ์ผ ๋๋ง ๊ธฐ๋ณธ๊ฐ์ ๋ฐํํฉ๋๋ค.
const notExist = null ?? "๊ธฐ๋ณธ๊ฐ ์๋";
console.log(notExist); // ์ถ๋ ฅ: "๊ธฐ๋ณธ๊ฐ ์๋"
10.3. ์ค๋ฌด ๋ํ์ ์ฝค๋ณด : ?. ์ ?? ๊ฐ์ด ์ฐ๊ธฐ
๐ ์ต์
๋ ์ฒด์ด๋์ผ๋ก ์๋ฌ๋ฅผ ๋ง๊ณ , ๋ ๋ณํฉ ์ฐ์ฐ์๋ก ๊ธฐ๋ณธ๊ฐ๊น์ง ์ธํ
ํ๋ ์๋ฒฝํ ์ค๋ฌด ํจํด์
๋๋ค.
const user = {
name: "์ด์์ ",
// profile ์ ๋ณด๊ฐ ์์
};
// "์ ์ ์ ๊ฑฐ์ฃผ ๋์(city)๋ฅผ ์ฐพ๋, ์ค๊ฐ์ ํฐ์ง์ง ์๊ฒ(?. ) ํ๊ณ ,
// ๋ง์ฝ ์ต์ข
์ ์ผ๋ก ๊ฐ์ด ์๋ค๋ฉด(?? ) '์ ์ ์์' ์ด๋ผ๊ณ ๋์์ค!"
const userCity = user?.profile?.city ?? "์ ์ ์์";
console.log(`๊ฑฐ์ฃผ์ง: ${userCity}`);
// ์ถ๋ ฅ: ๊ฑฐ์ฃผ์ง: ์ ์ ์์
11. String.replaceAll()
11.1. ๊ธฐ์กด replace()์ ํ๊ณ์ ๊ณผ๊ฑฐ์ ๋ฐฉ์
๐จ ๊ธฐ์กด์ replace()๋ ์ค์ง '์ฒซ ๋ฒ์งธ'๋ก ๋ฐ๊ฒฌ๋ ๋จ์ด ํ๋๋ง ๋ฐ๊ฟ์ฃผ๋ ์น๋ช
์ ์ธ ๋จ์ ์ด ์์์ต๋๋ค.
const text = "์ฌ๊ณผ, ๋ฐ๋๋, ์ฌ๊ณผ, ํฌ๋, ์ฌ๊ณผ";
// 1. ๊ธฐ์กด replace() ์ฌ์ฉ (์ฒซ ๋ฒ์งธ '์ฌ๊ณผ'๋ง '์๋ฐ'์ผ๋ก ๋ฐ๋)
const result1 = text.replace("์ฌ๊ณผ", "์๋ฐ");
console.log(result1);
// ์ถ๋ ฅ: "์๋ฐ, ๋ฐ๋๋, ์ฌ๊ณผ, ํฌ๋, ์ฌ๊ณผ"
// 2. [๊ณผ๊ฑฐ ES11 ์ด์ ] ์ ์ฒด๋ฅผ ๋ฐ๊พธ๋ ค๋ฉด ๋ณต์กํ '์ ๊ทํํ์(Regex)'๊ณผ ๊ธ๋ก๋ฒ ํ๋๊ทธ(g)๋ฅผ ๊ผญ ์จ์ผ ํ์ต๋๋ค.
const result2 = text.replace(/์ฌ๊ณผ/g, "์๋ฐ");
console.log(result2);
// ์ถ๋ ฅ: "์๋ฐ, ๋ฐ๋๋, ์๋ฐ, ํฌ๋, ์๋ฐ"
11.2. replaceAll()์ ์๋ฒฝํ ํด๊ฒฐ์ฑ
โจ ์ด์ ๋ณต์กํ ์ ๊ทํํ์ ๊ธฐํธ(/ /g) ์์ด๋, ์ง๊ด์ ์ธ ๋ฌธ์์ด๋ง์ผ๋ก ๋ชจ๋ ๋จ์ด๋ฅผ ์น ๋ค ๋ฐ๊ฟ ์ ์์ต๋๋ค.
const text = "์ฌ๊ณผ, ๋ฐ๋๋, ์ฌ๊ณผ, ํฌ๋, ์ฌ๊ณผ";
// โ
[์ต์ ES12 ๋ฐฉ์] ๊ทธ๋ฅ ๋ฐ๊พธ๊ณ ์ถ์ ๋จ์ด๋ฅผ ๋ฌธ์์ด๋ก ๋ฃ์ผ๋ฉด ๋!
const finalResult = text.replaceAll("์ฌ๊ณผ", "์๋ฐ");
console.log(finalResult);
// ์ถ๋ ฅ: "์๋ฐ, ๋ฐ๋๋, ์๋ฐ, ํฌ๋, ์๋ฐ"
11.3. ์ค๋ฌด ํ์ฉ ํ: ๋ฉ์๋ ์ฒด์ด๋๊ณผ ๋ฐ์ดํฐ ํด๋ ์ง
๐งน ์ฌ์ฉ์๊ฐ ์
๋ ฅํ ์ง์ ๋ถํ ๋ฐ์ดํฐ(ํน์๋ฌธ์ ๋ก์น ๋ฑ)๋ฅผ ํ ๋ฒ์ ๊น๋ํ๊ฒ ์ฒญ์ํ ๋ ๋งค์ฐ ์ ์ฉํฉ๋๋ค.
// ์ฌ์ฉ์๊ฐ ์
๋ ฅํ ์ง์ ๋ถํ ์ ํ๋ฒํธ ๋ฐ์ดํฐ
const dirtyPhone = "010-1234-5678 (๋ณธ์ธ)";
// '-' ๊ธฐํธ๋ฅผ ๋ชจ๋ ์์ ๊ณ , '(๋ณธ์ธ)' ์ด๋ผ๋ ๊ธ์๋ ์์ ๊ณ ์ถ์ ๋ (์ฒด์ด๋ ์ฌ์ฉ)
const cleanPhone = dirtyPhone
.replaceAll("-", "") // ๋ชจ๋ ํ์ดํ ์ ๊ฑฐ
.replaceAll(" (๋ณธ์ธ)", ""); // " (๋ณธ์ธ)" ํ
์คํธ ์ ๊ฑฐ
console.log(cleanPhone);
// ์ถ๋ ฅ: "01012345678"