Sam Baek, The Dev's Corner

๐Ÿš€ JavaScript ๋™์ž‘ ์›๋ฆฌ ์™„๋ฒฝ ๊ฐ€์ด๋“œ

04 Nov 2025

JavaScript ๋™์ž‘ ์›๋ฆฌ๋ž€ ๋ฌด์—‡์ธ๊ฐ€


JavaScript๋ฅผ ์‚ฌ์šฉํ•˜๋‹ค ๋ณด๋ฉด ์‹ ๊ธฐํ•œ ํ˜„์ƒ์„ ๊ฒฝํ—˜ํ•œ๋‹ค.
setTimeout์„ 0์ดˆ๋กœ ์„ค์ •ํ•ด๋„ ์ฝ”๋“œ๊ฐ€ ๋‚˜์ค‘์— ์‹คํ–‰๋˜๊ฑฐ๋‚˜,
ํ•จ์ˆ˜๋ฅผ ์„ ์–ธํ•˜๊ธฐ ์ „์— ํ˜ธ์ถœํ•ด๋„ ๋™์ž‘ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ๋‹ค.

์ด๋Š” ๋งˆ์น˜ ์‹๋‹น ์ฃผ๋ฐฉ๊ณผ ๊ฐ™๋‹ค.
์ฃผ๋ฐฉ์žฅ(JavaScript ์—”์ง„)์€ ํ•œ ๋ฒˆ์— ํ•œ ๊ฐ€์ง€ ์š”๋ฆฌ๋งŒ ๋งŒ๋“ค์ง€๋งŒ(์‹ฑ๊ธ€ ์Šค๋ ˆ๋“œ),
์˜ค๋ธ์— ์Œ์‹์„ ๋„ฃ๊ณ  ํƒ€์ด๋จธ๋ฅผ ๋งž์ถฐ๋‘๋ฉด(๋น„๋™๊ธฐ),
๊ทธ ์‚ฌ์ด์— ๋‹ค๋ฅธ ์š”๋ฆฌ๋ฅผ ๊ณ„์†ํ•  ์ˆ˜ ์žˆ๋‹ค.

JavaScript์˜ ๋™์ž‘ ์›๋ฆฌ๋ฅผ ์ดํ•ดํ•˜๋ฉด
์™œ ์ฝ”๋“œ๊ฐ€ ํŠน์ • ์ˆœ์„œ๋กœ ์‹คํ–‰๋˜๋Š”์ง€,
๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๊ฐ€ ์–ด๋–ป๊ฒŒ ์ด๋ฃจ์–ด์ง€๋Š”์ง€ ๋ช…ํ™•ํ•˜๊ฒŒ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

์™œ JavaScript ๋™์ž‘ ์›๋ฆฌ๋ฅผ ์•Œ์•„์•ผ ํ• ๊นŒ?


๋ฌธ์ œ 1: ์˜ˆ์ƒ์น˜ ๋ชปํ•œ ์‹คํ–‰ ์ˆœ์„œ
๋น„๋™๊ธฐ ์ฝ”๋“œ๊ฐ€ ์–ธ์ œ ์‹คํ–‰๋ ์ง€ ๋ชจ๋ฅด๋ฉด ๋ฒ„๊ทธ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

๋ฌธ์ œ 2: ์„ฑ๋Šฅ ๋ฌธ์ œ
๋ฌด๊ฑฐ์šด ์ž‘์—…์ด ํ™”๋ฉด์„ ๋ฉˆ์ถ”๊ฒŒ ๋งŒ๋“ ๋‹ค.

๋ฌธ์ œ 3: ๋ฉด์ ‘ ๋‹จ๊ณจ ์งˆ๋ฌธ
์ด๋ฒคํŠธ ๋ฃจํ”„, ์ฝœ ์Šคํƒ์€ ํ”„๋ก ํŠธ์—”๋“œ ๋ฉด์ ‘ ํ•„์ˆ˜ ์ฃผ์ œ

๋ฌธ์ œ 4: ๋””๋ฒ„๊น… ์–ด๋ ค์›€
์‹คํ–‰ ์ˆœ์„œ๋ฅผ ๋ชจ๋ฅด๋ฉด ์—๋Ÿฌ ์ถ”์ ์ด ํž˜๋“ค๋‹ค.

๊ธฐ๋ณธ ๊ฐœ๋… ์š”์•ฝ


๐Ÿท๏ธ JavaScript๋Š” ์‹ฑ๊ธ€ ์Šค๋ ˆ๋“œ


๊ฐœ๋…: ํ•œ ๋ฒˆ์— ํ•˜๋‚˜์˜ ์ž‘์—…๋งŒ ์ฒ˜๋ฆฌ

์‹๋‹น ๋น„์œ :
์ฃผ๋ฐฉ์žฅ์ด ํ•œ ๋ช…์ด๋ผ ํ•œ ๋ฒˆ์— ํ•˜๋‚˜์˜ ์š”๋ฆฌ๋งŒ ๋งŒ๋“ ๋‹ค.
ํ•˜์ง€๋งŒ ์˜ค๋ธ, ๋ƒ‰์žฅ๊ณ (Web APIs)๋ฅผ ํ™œ์šฉํ•ด์„œ
ํšจ์œจ์ ์œผ๋กœ ์—ฌ๋Ÿฌ ์š”๋ฆฌ๋ฅผ ๋™์‹œ์— ์ง„ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.

์žฅ์ : ๊ฐ„๋‹จํ•˜๊ณ  ์˜ˆ์ธก ๊ฐ€๋Šฅ
๋‹จ์ : ๋ฌด๊ฑฐ์šด ์ž‘์—…์ด ์ „์ฒด๋ฅผ ๋ง‰์„ ์ˆ˜ ์žˆ์Œ

๐Ÿท๏ธ JavaScript ์‹คํ–‰ ํ™˜๊ฒฝ


1. JavaScript ์—”์ง„ (V8, SpiderMonkey)


๊ตฌ์„ฑ ์š”์†Œ:

  • ํž™(Heap): ๋ณ€์ˆ˜, ๊ฐ์ฒด ์ €์žฅ (๋ฉ”๋ชจ๋ฆฌ)
  • ์ฝœ ์Šคํƒ(Call Stack): ํ•จ์ˆ˜ ์‹คํ–‰ ์ˆœ์„œ ๊ด€๋ฆฌ


2. Web APIs


๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์ œ๊ณตํ•˜๋Š” ๋น„๋™๊ธฐ ๊ธฐ๋Šฅ:

  • setTimeout / setInterval
  • DOM ์ด๋ฒคํŠธ
  • fetch (HTTP ์š”์ฒญ)
  • Promise


3. ํƒœ์Šคํฌ ํ (Task Queue)


๋น„๋™๊ธฐ ์ž‘์—…์ด ์™„๋ฃŒ๋˜๋ฉด ๋Œ€๊ธฐํ•˜๋Š” ๊ณณ

4. ์ด๋ฒคํŠธ ๋ฃจํ”„ (Event Loop)


์ฝœ ์Šคํƒ๊ณผ ํƒœ์Šคํฌ ํ๋ฅผ ๊ฐ์‹œํ•˜๋ฉฐ ์ž‘์—… ์กฐ์œจ

๐Ÿท๏ธ ์ฝœ ์Šคํƒ (Call Stack)


๊ฐœ๋…: ํ•จ์ˆ˜ ํ˜ธ์ถœ์„ ์ถ”์ ํ•˜๋Š” ์Šคํƒ ์ž๋ฃŒ๊ตฌ์กฐ

๋™์ž‘ ๋ฐฉ์‹:

  1. ํ•จ์ˆ˜ ํ˜ธ์ถœ โ†’ ์Šคํƒ์— push
  2. ํ•จ์ˆ˜ ์ข…๋ฃŒ โ†’ ์Šคํƒ์—์„œ pop
  3. LIFO (Last In First Out)


์˜ˆ์‹œ:

function first() {
  console.log("์ฒซ ๋ฒˆ์งธ");
  second();
  console.log("์ฒซ ๋ฒˆ์งธ ๋");
}

function second() {
  console.log("๋‘ ๋ฒˆ์งธ");
}

first();

// ์ฝœ ์Šคํƒ ์ˆœ์„œ:
// 1. first() push
// 2. console.log("์ฒซ ๋ฒˆ์งธ") push โ†’ pop
// 3. second() push
// 4. console.log("๋‘ ๋ฒˆ์งธ") push โ†’ pop
// 5. second() pop
// 6. console.log("์ฒซ ๋ฒˆ์งธ ๋") push โ†’ pop
// 7. first() pop


๐Ÿท๏ธ ์ด๋ฒคํŠธ ๋ฃจํ”„ (Event Loop)


๊ฐœ๋…: ์ฝœ ์Šคํƒ์ด ๋น„์–ด์žˆ์œผ๋ฉด ํƒœ์Šคํฌ ํ์—์„œ ์ž‘์—…์„ ๊ฐ€์ ธ์˜ด

๋™์ž‘ ์›๋ฆฌ:

1. ์ฝœ ์Šคํƒ ํ™•์ธ
2. ๋น„์–ด์žˆ์œผ๋ฉด โ†’ ํƒœ์Šคํฌ ํ์—์„œ ๊ฐ€์ ธ์˜ค๊ธฐ
3. ๋น„์–ด์žˆ์ง€ ์•Š์œผ๋ฉด โ†’ ๋Œ€๊ธฐ
4. ๋ฐ˜๋ณต


ํ•ต์‹ฌ ๊ทœ์น™:
์ฝœ ์Šคํƒ์ด ์™„์ „ํžˆ ๋น„์–ด์•ผ๋งŒ ํƒœ์Šคํฌ ํ์˜ ์ž‘์—… ์‹คํ–‰

๐Ÿท๏ธ ๋งคํฌ๋กœํƒœ์Šคํฌ vs ๋งˆ์ดํฌ๋กœํƒœ์Šคํฌ


๋งคํฌ๋กœํƒœ์Šคํฌ (Macrotask)


  • setTimeout
  • setInterval
  • setImmediate
  • I/O ์ž‘์—…


๋งˆ์ดํฌ๋กœํƒœ์Šคํฌ (Microtask)


  • Promise.then
  • queueMicrotask
  • MutationObserver


์šฐ์„ ์ˆœ์œ„: ๋งˆ์ดํฌ๋กœํƒœ์Šคํฌ๊ฐ€ ๋งคํฌ๋กœํƒœ์Šคํฌ๋ณด๋‹ค ๋จผ์ € ์‹คํ–‰

์‹คํ–‰ ์ˆœ์„œ:

  1. ์ฝœ ์Šคํƒ ์‹คํ–‰
  2. ๋ชจ๋“  ๋งˆ์ดํฌ๋กœํƒœ์Šคํฌ ์‹คํ–‰
  3. ๋งคํฌ๋กœํƒœ์Šคํฌ ํ•˜๋‚˜ ์‹คํ–‰
  4. ๋‹ค์‹œ ๋งˆ์ดํฌ๋กœํƒœ์Šคํฌ ๋ชจ๋‘ ์‹คํ–‰
  5. ๋ฐ˜๋ณต


์‹ค์ „ ์˜ˆ์‹œ


์ฝœ ์Šคํƒ ๋™์ž‘ ์ดํ•ดํ•˜๊ธฐ


function multiply(a, b) {
  return a * b;
}

function square(n) {
  return multiply(n, n);
}

function printSquare(n) {
  const result = square(n);
  console.log(result);
}

printSquare(4);

// ์ฝœ ์Šคํƒ ๋ณ€ํ™”:
// 1. [printSquare(4)]
// 2. [printSquare(4), square(4)]
// 3. [printSquare(4), square(4), multiply(4, 4)]
// 4. [printSquare(4), square(4)]  // multiply ๋ฆฌํ„ด
// 5. [printSquare(4)]  // square ๋ฆฌํ„ด
// 6. [printSquare(4), console.log(16)]
// 7. []  // ๋ชจ๋‘ ์™„๋ฃŒ

// ์ถœ๋ ฅ: 16


๋น„๋™๊ธฐ ์ฝ”๋“œ ์‹คํ–‰ ์ˆœ์„œ


console.log("1");

setTimeout(() => {
  console.log("2");
}, 0);

console.log("3");

// ์ถœ๋ ฅ:
// 1
// 3
// 2

// ์™œ?
// 1. console.log("1") ์‹คํ–‰ (์ฝœ ์Šคํƒ)
// 2. setTimeout์€ Web API๋กœ ์ด๋™ (์ฝœ ์Šคํƒ์—์„œ ์ œ๊ฑฐ)
// 3. console.log("3") ์‹คํ–‰ (์ฝœ ์Šคํƒ)
// 4. ์ฝœ ์Šคํƒ ๋น„์›€
// 5. ์ด๋ฒคํŠธ ๋ฃจํ”„๊ฐ€ ํƒœ์Šคํฌ ํ์—์„œ setTimeout ์ฝœ๋ฐฑ ๊ฐ€์ ธ์˜ด
// 6. console.log("2") ์‹คํ–‰


Promise vs setTimeout ์šฐ์„ ์ˆœ์œ„


console.log("์‹œ์ž‘");

setTimeout(() => {
  console.log("setTimeout");
}, 0);

Promise.resolve()
  .then(() => {
    console.log("Promise 1");
  })
  .then(() => {
    console.log("Promise 2");
  });

console.log("๋");

// ์ถœ๋ ฅ ์ˆœ์„œ:
// ์‹œ์ž‘
// ๋
// Promise 1
// Promise 2
// setTimeout

// ์ด์œ :
// 1. ๋™๊ธฐ ์ฝ”๋“œ ๋จผ์ € (์‹œ์ž‘, ๋)
// 2. ๋งˆ์ดํฌ๋กœํƒœ์Šคํฌ (Promise)
// 3. ๋งคํฌ๋กœํƒœ์Šคํฌ (setTimeout)


์ด๋ฒคํŠธ ๋ฃจํ”„ ์ƒ์„ธ ์˜ˆ์ œ


console.log("Script start");

setTimeout(function timeout() {
  console.log("setTimeout");
}, 0);

Promise.resolve()
  .then(function promise1() {
    console.log("Promise 1");
  })
  .then(function promise2() {
    console.log("Promise 2");
  });

requestAnimationFrame(function animation() {
  console.log("requestAnimationFrame");
});

console.log("Script end");

// ์ถœ๋ ฅ ์ˆœ์„œ:
// Script start
// Script end
// Promise 1
// Promise 2
// requestAnimationFrame (๋‹ค์Œ ํ”„๋ ˆ์ž„)
// setTimeout

// ์‹คํ–‰ ์ˆœ์„œ:
// 1. ๋™๊ธฐ ์ฝ”๋“œ ์‹คํ–‰ (์ฝœ ์Šคํƒ)
// 2. ๋งˆ์ดํฌ๋กœํƒœ์Šคํฌ ํ ๋น„์šฐ๊ธฐ (Promise)
// 3. ๋ Œ๋”๋ง (requestAnimationFrame)
// 4. ๋งคํฌ๋กœํƒœ์Šคํฌ ํ์—์„œ ํ•˜๋‚˜ ์‹คํ–‰ (setTimeout)


๋ฌดํ•œ ๋ฃจํ”„๋กœ ์ธํ•œ ์Šคํƒ ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ


// โŒ ์Šคํƒ ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ ๋ฐœ์ƒ
function recursiveFunction() {
  recursiveFunction();
}

// recursiveFunction(); // Uncaught RangeError: Maximum call stack size exceeded

// โœ… setTimeout์œผ๋กœ ํ•ด๊ฒฐ
function safeRecursive() {
  console.log("์‹คํ–‰");
  setTimeout(safeRecursive, 0);
}

// safeRecursive(); // ๋ฌดํ•œ ์‹คํ–‰๋˜์ง€๋งŒ ์Šคํƒ์€ ์•ˆ์ „


์ด์œ :
setTimeout์€ ์ฝœ๋ฐฑ์„ ํƒœ์Šคํฌ ํ๋กœ ๋ณด๋‚ด๋ฏ€๋กœ
์ฝœ ์Šคํƒ์ด ๋งค๋ฒˆ ๋น„์›Œ์ง„๋‹ค.

๋ธ”๋กœํ‚น vs ๋…ผ๋ธ”๋กœํ‚น


๋ธ”๋กœํ‚น ์ฝ”๋“œ (๋‚˜์œ ์˜ˆ)


// โŒ 5์ดˆ ๋™์•ˆ ํ™”๋ฉด์ด ๋ฉˆ์ถค
const startTime = Date.now();
while (Date.now() - startTime < 5000) {
  // 5์ดˆ ๋Œ€๊ธฐ
}
console.log("5์ดˆ ๊ฒฝ๊ณผ");


๋…ผ๋ธ”๋กœํ‚น ์ฝ”๋“œ (์ข‹์€ ์˜ˆ)


// โœ… ํ™”๋ฉด์ด ๋ฉˆ์ถ”์ง€ ์•Š์Œ
setTimeout(() => {
  console.log("5์ดˆ ๊ฒฝ๊ณผ");
}, 5000);

console.log("๋‹ค๋ฅธ ์ž‘์—… ๊ณ„์† ๊ฐ€๋Šฅ");


์‹คํ–‰ ์ปจํ…์ŠคํŠธ (Execution Context)


๐Ÿท๏ธ ์‹คํ–‰ ์ปจํ…์ŠคํŠธ๋ž€?


๊ฐœ๋…: ์ฝ”๋“œ๊ฐ€ ์‹คํ–‰๋˜๋Š” ํ™˜๊ฒฝ

๊ตฌ์„ฑ ์š”์†Œ:

  1. Variable Environment: ๋ณ€์ˆ˜, ํ•จ์ˆ˜ ์„ ์–ธ ์ €์žฅ
  2. Lexical Environment: ์Šค์ฝ”ํ”„ ์ฒด์ธ
  3. this ๋ฐ”์ธ๋”ฉ


๐Ÿท๏ธ ์‹คํ–‰ ์ปจํ…์ŠคํŠธ ์ƒ์„ฑ ๊ณผ์ •


1. Creation Phase (์ƒ์„ฑ ๋‹จ๊ณ„)


console.log(name); // undefined (ํ˜ธ์ด์ŠคํŒ…)
var name = "ํ™๊ธธ๋™";

// Creation Phase:
// - name ๋ณ€์ˆ˜ ์„ ์–ธ (๊ฐ’์€ undefined)
// - ํ•จ์ˆ˜ ์„ ์–ธ ์ „์ฒด๋ฅผ ๋ฉ”๋ชจ๋ฆฌ์— ์ €์žฅ


2. Execution Phase (์‹คํ–‰ ๋‹จ๊ณ„)


var name = "ํ™๊ธธ๋™";
console.log(name); // "ํ™๊ธธ๋™"

// Execution Phase:
// - name์— "ํ™๊ธธ๋™" ํ• ๋‹น
// - ์ฝ”๋“œ ํ•œ ์ค„์”ฉ ์‹คํ–‰


๐Ÿท๏ธ ํ˜ธ์ด์ŠคํŒ… (Hoisting)


๊ฐœ๋…: ์„ ์–ธ์ด ์Šค์ฝ”ํ”„ ์ตœ์ƒ๋‹จ์œผ๋กœ ๋Œ์–ด์˜ฌ๋ ค์ง€๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋™์ž‘

var ํ˜ธ์ด์ŠคํŒ…


console.log(age); // undefined
var age = 30;

// ์œ„ ์ฝ”๋“œ๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ ์ด๋ ‡๊ฒŒ ๋™์ž‘:
var age;
console.log(age); // undefined
age = 30;


ํ•จ์ˆ˜ ํ˜ธ์ด์ŠคํŒ…


// โœ… ํ•จ์ˆ˜ ์„ ์–ธ์‹: ํ˜ธ์ด์ŠคํŒ…๋จ
sayHello(); // "Hello!"

function sayHello() {
  console.log("Hello!");
}

// โŒ ํ•จ์ˆ˜ ํ‘œํ˜„์‹: ํ˜ธ์ด์ŠคํŒ… ์•ˆ ๋จ
sayBye(); // TypeError: sayBye is not a function

var sayBye = function () {
  console.log("Bye!");
};


let/const๋Š” ํ˜ธ์ด์ŠคํŒ…๋˜์ง€๋งŒ TDZ


// โŒ ReferenceError
console.log(name); // Cannot access 'name' before initialization
let name = "ํ™๊ธธ๋™";

// TDZ (Temporal Dead Zone):
// ์„ ์–ธ์€ ํ˜ธ์ด์ŠคํŒ…๋˜์ง€๋งŒ ์ดˆ๊ธฐํ™” ์ „๊นŒ์ง€ ์ ‘๊ทผ ๋ถˆ๊ฐ€


์Šค์ฝ”ํ”„ (Scope)


๐Ÿท๏ธ ์Šค์ฝ”ํ”„๋ž€?


๊ฐœ๋…: ๋ณ€์ˆ˜์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ๋ฒ”์œ„

1. ์ „์—ญ ์Šค์ฝ”ํ”„ (Global Scope)


const globalVar = "์ „์—ญ ๋ณ€์ˆ˜";

function test() {
  console.log(globalVar); // ์ ‘๊ทผ ๊ฐ€๋Šฅ
}


2. ํ•จ์ˆ˜ ์Šค์ฝ”ํ”„ (Function Scope)


function outer() {
  const outerVar = "outer";

  function inner() {
    console.log(outerVar); // ์ ‘๊ทผ ๊ฐ€๋Šฅ (์Šค์ฝ”ํ”„ ์ฒด์ธ)
  }

  inner();
}

// console.log(outerVar); // ReferenceError


3. ๋ธ”๋ก ์Šค์ฝ”ํ”„ (Block Scope)


if (true) {
  let blockVar = "๋ธ”๋ก ๋ณ€์ˆ˜";
  const blockConst = "๋ธ”๋ก ์ƒ์ˆ˜";
  var functionVar = "ํ•จ์ˆ˜ ๋ณ€์ˆ˜";
}

// console.log(blockVar); // ReferenceError
// console.log(blockConst); // ReferenceError
console.log(functionVar); // "ํ•จ์ˆ˜ ๋ณ€์ˆ˜" (var๋Š” ๋ธ”๋ก ์Šค์ฝ”ํ”„ ๋ฌด์‹œ)


๐Ÿท๏ธ ์Šค์ฝ”ํ”„ ์ฒด์ธ


const global = "์ „์—ญ";

function outer() {
  const outerVar = "outer";

  function inner() {
    const innerVar = "inner";
    console.log(innerVar); // inner
    console.log(outerVar); // outer (์ƒ์œ„ ์Šค์ฝ”ํ”„ ์ฐธ์กฐ)
    console.log(global); // ์ „์—ญ (์ตœ์ƒ์œ„ ์Šค์ฝ”ํ”„ ์ฐธ์กฐ)
  }

  inner();
}

outer();

// ์Šค์ฝ”ํ”„ ์ฒด์ธ:
// inner โ†’ outer โ†’ global


ํด๋กœ์ € (Closure)


๐Ÿท๏ธ ํด๋กœ์ €๋ž€?


๊ฐœ๋…: ํ•จ์ˆ˜๊ฐ€ ์„ ์–ธ๋  ๋•Œ์˜ ๋ ‰์‹œ์ปฌ ํ™˜๊ฒฝ์„ ๊ธฐ์–ตํ•˜๋Š” ํ•จ์ˆ˜

function makeCounter() {
  let count = 0; // ์™ธ๋ถ€ ํ•จ์ˆ˜์˜ ๋ณ€์ˆ˜

  return function () {
    count++;
    return count;
  };
}

const counter = makeCounter();
console.log(counter()); // 1
console.log(counter()); // 2
console.log(counter()); // 3

// counter ํ•จ์ˆ˜๋Š” count ๋ณ€์ˆ˜๋ฅผ ๊ธฐ์–ตํ•จ (ํด๋กœ์ €)


๐Ÿท๏ธ ํด๋กœ์ € ํ™œ์šฉ ์˜ˆ์‹œ


1. ๋ฐ์ดํ„ฐ ์€๋‹‰ (Private ๋ณ€์ˆ˜)


function createWallet() {
  let balance = 0; // private ๋ณ€์ˆ˜

  return {
    deposit(amount) {
      balance += amount;
      return balance;
    },
    withdraw(amount) {
      if (balance >= amount) {
        balance -= amount;
        return balance;
      }
      return "์ž”์•ก ๋ถ€์กฑ";
    },
    getBalance() {
      return balance;
    },
  };
}

const myWallet = createWallet();
myWallet.deposit(1000); // 1000
myWallet.withdraw(300); // 700
console.log(myWallet.getBalance()); // 700

// balance์— ์ง์ ‘ ์ ‘๊ทผ ๋ถˆ๊ฐ€
console.log(myWallet.balance); // undefined


2. ํ•จ์ˆ˜ ํŒฉํ† ๋ฆฌ


function makeMultiplier(multiplier) {
  return function (number) {
    return number * multiplier;
  };
}

const double = makeMultiplier(2);
const triple = makeMultiplier(3);

console.log(double(5)); // 10
console.log(triple(5)); // 15


3. ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ


function setupButtons() {
  for (let i = 0; i < 3; i++) {
    const button = document.getElementById(`btn${i}`);
    button.addEventListener("click", function () {
      console.log(`๋ฒ„ํŠผ ${i} ํด๋ฆญ`); // i๋ฅผ ๊ธฐ์–ต (ํด๋กœ์ €)
    });
  }
}

// var ์‚ฌ์šฉ ์‹œ ๋ฌธ์ œ
function setupButtonsBad() {
  for (var i = 0; i < 3; i++) {
    const button = document.getElementById(`btn${i}`);
    button.addEventListener("click", function () {
      console.log(`๋ฒ„ํŠผ ${i} ํด๋ฆญ`); // ํ•ญ์ƒ 3 ์ถœ๋ ฅ
    });
  }
}


๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ ํŒจํ„ด


๐Ÿท๏ธ ์ฝœ๋ฐฑ (Callback)


function fetchUser(callback) {
  setTimeout(() => {
    const user = { name: "ํ™๊ธธ๋™", age: 30 };
    callback(user);
  }, 1000);
}

fetchUser((user) => {
  console.log(user); // { name: "ํ™๊ธธ๋™", age: 30 }
});


๋ฌธ์ œ์ : ์ฝœ๋ฐฑ ์ง€์˜ฅ (Callback Hell)

// โŒ ์ฝœ๋ฐฑ ์ง€์˜ฅ
fetchUser((user) => {
  fetchPosts(user.id, (posts) => {
    fetchComments(posts[0].id, (comments) => {
      console.log(comments);
    });
  });
});


๐Ÿท๏ธ Promise


function fetchUser() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      const user = { name: "ํ™๊ธธ๋™", age: 30 };
      resolve(user);
    }, 1000);
  });
}

fetchUser()
  .then((user) => {
    console.log(user);
    return fetchPosts(user.id);
  })
  .then((posts) => {
    console.log(posts);
    return fetchComments(posts[0].id);
  })
  .then((comments) => {
    console.log(comments);
  })
  .catch((error) => {
    console.error(error);
  });


๐Ÿท๏ธ Async/Await


async function getUserData() {
  try {
    const user = await fetchUser();
    console.log(user);

    const posts = await fetchPosts(user.id);
    console.log(posts);

    const comments = await fetchComments(posts[0].id);
    console.log(comments);
  } catch (error) {
    console.error(error);
  }
}

getUserData();


์žฅ์ : ๋™๊ธฐ ์ฝ”๋“œ์ฒ˜๋Ÿผ ์ฝ๊ธฐ ์‰ฌ์›€

์‹ค์ „ ์ฒดํฌ๋ฆฌ์ŠคํŠธ


โœ… ์ฝœ ์Šคํƒ ์ดํ•ด


  • ํ•จ์ˆ˜ ํ˜ธ์ถœ ์ˆœ์„œ๋ฅผ ์ถ”์ ํ•  ์ˆ˜ ์žˆ๋Š”๊ฐ€?
  • ์Šคํƒ ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ ์›์ธ์„ ์•„๋Š”๊ฐ€?
  • ์žฌ๊ท€ ํ•จ์ˆ˜์˜ ์ฝœ ์Šคํƒ์„ ์ดํ•ดํ•˜๋Š”๊ฐ€?


โœ… ์ด๋ฒคํŠธ ๋ฃจํ”„


  • ๋น„๋™๊ธฐ ์ฝ”๋“œ์˜ ์‹คํ–‰ ์ˆœ์„œ๋ฅผ ์˜ˆ์ธกํ•  ์ˆ˜ ์žˆ๋Š”๊ฐ€?
  • ๋งˆ์ดํฌ๋กœํƒœ์Šคํฌ์™€ ๋งคํฌ๋กœํƒœ์Šคํฌ ์ฐจ์ด๋ฅผ ์•„๋Š”๊ฐ€?
  • ๋ธ”๋กœํ‚น ์ฝ”๋“œ๋ฅผ ํ”ผํ•  ์ˆ˜ ์žˆ๋Š”๊ฐ€?


โœ… ์‹คํ–‰ ์ปจํ…์ŠคํŠธ


  • ํ˜ธ์ด์ŠคํŒ…์„ ์ดํ•ดํ•˜๋Š”๊ฐ€?
  • var, let, const ์ฐจ์ด๋ฅผ ์•„๋Š”๊ฐ€?
  • TDZ(Temporal Dead Zone)๋ฅผ ์•„๋Š”๊ฐ€?


โœ… ์Šค์ฝ”ํ”„์™€ ํด๋กœ์ €


  • ์Šค์ฝ”ํ”„ ์ฒด์ธ์„ ์ดํ•ดํ•˜๋Š”๊ฐ€?
  • ํด๋กœ์ €๋ฅผ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋Š”๊ฐ€?
  • private ๋ณ€์ˆ˜๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š”๊ฐ€?


โœ… ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ


  • Promise๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋Š”๊ฐ€?
  • async/await๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š”๊ฐ€?
  • ์—๋Ÿฌ ์ฒ˜๋ฆฌ๋ฅผ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ํ•˜๋Š”๊ฐ€?


์š”์•ฝ


JavaScript ๋™์ž‘ ์›๋ฆฌ๋ฅผ ์ดํ•ดํ•˜๋ฉด ๋” ๋‚˜์€ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.

๐Ÿ’Ž ํ•ต์‹ฌ ํฌ์ธํŠธ:

  1. ์‹ฑ๊ธ€ ์Šค๋ ˆ๋“œ: ํ•œ ๋ฒˆ์— ํ•˜๋‚˜์”ฉ ์ฒ˜๋ฆฌ
  2. ์ด๋ฒคํŠธ ๋ฃจํ”„: ๋น„๋™๊ธฐ๋ฅผ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•จ
  3. ์ฝœ ์Šคํƒ: ํ•จ์ˆ˜ ์‹คํ–‰ ์ˆœ์„œ ๊ด€๋ฆฌ
  4. ๋งˆ์ดํฌ๋กœํƒœ์Šคํฌ ์šฐ์„ : Promise๊ฐ€ setTimeout๋ณด๋‹ค ๋จผ์ €
  5. ํ˜ธ์ด์ŠคํŒ…: ์„ ์–ธ์ด ๋Œ์–ด์˜ฌ๋ ค์ง
  6. ํด๋กœ์ €: ๋ ‰์‹œ์ปฌ ํ™˜๊ฒฝ ๊ธฐ์–ต


๐Ÿš€ ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ ์ง„ํ™”:

1๋‹จ๊ณ„: Callback (์ฝœ๋ฐฑ ์ง€์˜ฅ ๋ฌธ์ œ)
2๋‹จ๊ณ„: Promise (์ฒด์ด๋‹ ๊ฐ€๋Šฅ)
3๋‹จ๊ณ„: Async/Await (๋™๊ธฐ ์ฝ”๋“œ์ฒ˜๋Ÿผ ์ž‘์„ฑ)

โš ๏ธ ์ฃผ์˜์‚ฌํ•ญ:

  • ๋ฌด๊ฑฐ์šด ๋™๊ธฐ ์ž‘์—…์€ ํ™”๋ฉด์„ ๋ฉˆ์ถค
  • setTimeout(fn, 0)๋„ ์ฆ‰์‹œ ์‹คํ–‰๋˜์ง€ ์•Š์Œ
  • var ๋Œ€์‹  let/const ์‚ฌ์šฉ
  • ํด๋กœ์ €๋กœ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜ ์ฃผ์˜


๐Ÿ“Š ์‹คํ–‰ ์ˆœ์„œ ์ •๋ฆฌ:

1. ๋™๊ธฐ ์ฝ”๋“œ (์ฝœ ์Šคํƒ)
2. ๋งˆ์ดํฌ๋กœํƒœ์Šคํฌ (Promise, queueMicrotask)
3. ๋ Œ๋”๋ง (requestAnimationFrame)
4. ๋งคํฌ๋กœํƒœ์Šคํฌ (setTimeout, setInterval)


JavaScript๋Š” ์‹ฑ๊ธ€ ์Šค๋ ˆ๋“œ์ง€๋งŒ
์ด๋ฒคํŠธ ๋ฃจํ”„์™€ Web APIs ๋•๋ถ„์—
๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค.

์ด ์›๋ฆฌ๋ฅผ ์ดํ•ดํ•˜๋ฉด
์ฝ”๋“œ์˜ ์‹คํ–‰ ์ˆœ์„œ๋ฅผ ์˜ˆ์ธกํ•˜๊ณ ,
ํšจ์œจ์ ์ธ ๋น„๋™๊ธฐ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋ฉฐ,
๋””๋ฒ„๊น…๋„ ํ›จ์”ฌ ์‰ฌ์›Œ์ง„๋‹ค.