ํ™ˆ์œผ๋กœ
โ† ์ฑ…์žฅ์œผ๋กœ

๐ŸŒŸ ๋ชจ๋˜์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ : 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"