[๐Ÿ“– ๋ชจ๋˜ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋”ฅ๋‹ค์ด๋ธŒ] 24์žฅ. ํด๋กœ์ €

๋…ธ์˜์™„ยท2023๋…„ 12์›” 20์ผ
0

JavaScript(Deep Dive)

๋ชฉ๋ก ๋ณด๊ธฐ
19/23
post-thumbnail
post-custom-banner

ํด๋กœ์ €

ํด๋กœ์ €๋Š” ๋‚œํ•ดํ•˜๊ธฐ๋กœ ์œ ๋ช…ํ•œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๊ฐœ๋… ์ค‘ ํ•˜๋‚˜, ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๊ณ ์œ ์˜ ๊ฐœ๋…์€ ์•„๋‹ˆ๋‹ค.

ํด๋กœ์ €๋Š” ํ•จ์ˆ˜๋ฅผ ์ผ๊ธ‰ ๊ฐ์ฒด๋กœ ์ทจ๊ธ‰ํ•˜๋Š” ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ์–ธ์–ด์—์„œ ์‚ฌ์šฉ๋˜๋Š” ์ค‘์š”ํ•œ ํŠน์„ฑ์ด๋‹ค.

ํด๋กœ์ €๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๊ณ ์œ ์˜ ๊ฐœ๋…์ด ์•„๋‹ˆ๋ฏ€๋กœ ECMAScript ์‚ฌ์–‘์— ๋“ฑ์žฅํ•˜์ง€ ์•Š๋Š”๋‹ค. MDN์—์„œ๋Š” ํด๋กœ์ œ์— ๋Œ€ํ•ด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ •์˜ํ•˜๊ณ  ์žˆ๋‹ค.
"ํด๋กœ์ €๋Š” ํ•จ์ˆ˜์™€ ๊ทธ ํ•จ์ˆ˜๊ฐ€ ์„ ์–ธ๋œ ๋ ‰์‹œ์ปฌ ํ™˜๊ฒฝ๊ณผ์˜ ์กฐํ•ฉ์ด๋‹ค".

ํด๋กœ์ €๋ฅผ ์ดํ•ดํ•˜๋ ค๋ฉด ๋จผ์ € ๋ ‰์‹œ์ปฌ ํ™˜๊ฒฝ, ์ฆ‰ ๋ ‰์‹œ์ปฌ ์Šค์ฝ”ํ”„๋ฅผ ์ดํ•ดํ•ด์•ผ ํ•œ๋‹ค.

const x = 1;

function outerFunc() {
  const x = 10;
  
  function innerFunc() {
    console.log(x); // 10
  }
  
  innerFunc();
}

outerFunc();
const x = 1;

function outerFunc() {
  const x = 10;
  innerFunc();
}

function innerFunc() {
  console.log(x); // 1
}

outerFunc()

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ๋ ‰์‹œ์ปฌ ์Šค์ฝ”ํ”„๋ฅผ ๋”ฐ๋ฅด๋Š” ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด์ด๋‹ค.

1. ๋ ‰์‹œ์ปฌ ์Šค์ฝ”ํ”„

๋ ‰์‹œ์ปฌ ์Šค์ฝ”ํ”„๋ฅผ ์‹คํ–‰ ์ปจํ…์ŠคํŠธ์˜ ๊ด€์ ์—์„œ ์‚ดํŽด๋ณด์ž.

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์—”์ง„์€ ํ•จ์ˆ˜๋ฅผ ์–ด๋””์„œ ํ˜ธ์ถœํ–ˆ๋Š”์ง€๊ฐ€ ์•„๋‹ˆ๋ผ ํ•จ์ˆ˜๋ฅผ ์–ด๋””์„œ ์ •์˜ํ–ˆ๋Š”์ง€์— ๋”ฐ๋ผ ์ƒ์œ„ ์Šค์ฝ”ํ”„๋ฅผ ๊ฒฐ์ •ํ•œ๋‹ค. ์ด๋ฅผ ๋ ‰์‹œ์ปฌ ์Šค์ฝ”ํ”„(์ •์  ์Šค์ฝ”ํ”„)๋ผ ํ•œ๋‹ค.

๋ ‰์‹œ์ปฌ ํ™˜๊ฒฝ์˜ "์™ธ๋ถ€ ๋ ‰์‹œ์ปฌ ํ™˜๊ฒฝ์— ๋Œ€ํ•œ ์ฐธ์กฐ"์— ์ €์žฅํ•  ์ฐธ์กฐ๊ฐ’. ์ฆ‰ ์ƒ์œ„ ์Šค์ฝ”ํ”„์— ๋Œ€ํ•œ ์ฐธ์กฐ๋Š” ํ•จ์ˆ˜ ์ •์˜๊ฐ€ ํ‰๊ฐ€๋˜๋Š” ์‹œ์ ์— ํ•จ์ˆ˜๊ฐ€ ์ •์˜๋œ ํ™˜๊ฒฝ(์œ„์น˜)์— ์˜ํ•ด ๊ฒฐ์ •๋œ๋‹ค. ์ด๊ฒƒ์ด ๋ฐ”๋กœ ๋ ‰์‹œ์ปฌ ์Šค์ฝ”ํ”„๋‹ค.

2. ํ•จ์ˆ˜ ๊ฐ์ฒด์˜ ๋‚ด๋ถ€ ์Šฌ๋กฏ [[Environment]]

ํ•จ์ˆ˜๊ฐ€ ์ •์˜ ํ™˜๊ฒฝ(์œ„์น˜)๊ณผ ํ˜ธ์ถœ๋˜๋Š” ํ™˜๊ฒฝ(์œ„์น˜)๋Š” ๋‹ค๋ฅผ ์ˆ˜ ์žˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋ ‰์‹œ์ปฌ ์Šค์ฝ”ํ”„๊ฐ€ ๊ฐ€๋Šฅํ•˜๋ ค๋ฉด ํ•จ์ˆ˜๋Š” ์ž์‹ ์ด ํ˜ธ์ถœ๋˜๋Š” ํ™˜๊ฒฝ๊ณผ๋Š” ์ƒ๊ด€์—†์ด ์ž์‹ ์ด ์ •์˜๋œ ํ™˜๊ฒฝ, ์ฆ‰ ์ƒ์œ„ ์Šค์ฝ”ํ”„(ํ•จ์ˆ˜ ์ •์˜๊ฐ€ ์œ„์น˜ํ•˜๋Š” ์Šค์ฝ”ํŒŒ๊ฐ€ ๋ฐ”๋กœ ์ƒ์œ„์Šค์ฝ”ํ”„)๋ฅผ ๊ธฐ์–ตํ•ด์•ผ ํ•œ๋‹ค.

์ด๋ฅผ ์œ„ํ•ด ํ•จ์ˆ˜๋Š” ์ž์‹ ์˜ ๋‚ด๋ถ€ ์Šฌ๋กฏ [[Envirnoment]]์— ์ž์‹ ์ด ์ •์˜๋œ ํ™˜๊ฒฝ, ์ฆ‰ ์ƒ์œ„ ์Šค์ฝ”ํ”„์˜ ์ฐธ์กฐ๋ฅผ ์ €์žฅํ•œ๋‹ค.

์ž์‹ ์˜ [[Envirnoment]]์— ์ €์žฅ๋œ ์ƒ์œ„ ์Šค์ฝ”ํ”„์˜ ์ฐธ์กฐ๋Š” ํ˜„์žฌ ์‹คํ–‰ ์ค‘์ธ ์‹คํ–‰ ์ปจํ…์ŠคํŠธ์˜ ๋ ‰์‹œ์ปฌํ™˜๊ฒฝ์„ ๊ฐ€๋ฆฌํ‚จ๋‹ค.

const x = 1;

function foo() {
  const x = 10;
  
  // ์ƒ์œ„ ์Šค์ฝ”ํ”„๋Š” ํ•จ์ˆ˜ ์ •์˜ ํ™˜๊ฒฝ(์œ„์น˜)์— ๋”ฐ๋ผ ๊ฒฐ์ •๋œ๋‹ค.
  // ํ•จ์ˆ˜ ํ˜ธ์ถœ ์œ„์น˜์™€ ์ƒ์œ„ ์Šค์ฝ”ํ”„๋Š” ์•„๋ฌด๋Ÿฐ ๊ด€๊ณ„๊ฐ€ ์—†๋‹ค.
  bar();
}

// ํ•จ์ˆ˜ bar๋Š” ์ž์‹ ์˜ ์ƒ์œ„ ์Šค์ฝ”ํ”„, ์ฆ‰ ์ „์—ญ ๋ ‰์‹œ์ปฌ ํ™˜๊ฒฝ์„ [[Environment]]์— ์žฅํ•˜์—ฌ ๊ธฐ์–ตํ•œ๋‹ค.
function bar() {
  console.log(x);
}

foo()
bar()

๊ทธ๋ฆผ์˜ โ‘ ์€ ์ „์—ญ ์ฝ”๋“œ ํ‰๊ฐ€ ์‹œ์ ์—์„œ foo์™€ barํ•จ์ˆ˜ ๊ฐ์ฒด๊ฐ€ ์ƒ์„ฑ๋˜๋ฉฐ ๊ฐ ํ•จ์ˆ˜ ๊ฐ์ฒด์˜ ๋‚ด๋ถ€ ์Šฌ๋กฏ [[Environment]]์— ์ƒ์œ„ ์Šค์ฝ”ํ”„๊ฐ€ ์ €์žฅ๋œ๋‹ค.

fooํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋˜๋ฉด โ‘ก fooํ•จ์ˆ˜์˜ ๋ ‰์‹œ์ปฌ ํ™˜๊ฒฝ์ด ์ƒ์„ฑ๋˜๋ฉฐ ์™ธ๋ถ€ ๋ ‰์‹œ์ปฌ ํ™˜๊ฒฝ ํ™˜๊ฒฝ์— ๋Œ€ํ•œ ์ฐธ์กฐ์— ์ „์—ญ ๋ ‰์‹œ์ปฌ ํ™˜๊ฒฝ์˜ ์ฐธ์กฐ(ํ•จ์ˆ˜ ๊ฐ์ฒด์˜ ๋‚ด๋ถ€ ์Šฌ๋กฏ [[Environment]]์— ์ €์žฅ๋œ)๊ฐ€ ์ €์žฅ๋œ๋‹ค.

barํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋˜๋ฉด โ‘ข barํ•จ์ˆ˜์˜ ๋ ‰์‹œ์ปฌ ํ™˜๊ฒฝ์ด ์ƒ์„ฑ๋˜๋ฉฐ ์™ธ๋ถ€ ๋ ‰์‹œ์ปฌ ํ™˜๊ฒฝ ํ™˜๊ฒฝ์— ๋Œ€ํ•œ ์ฐธ์กฐ์— ์ „์—ญ ๋ ‰์‹œ์ปฌ ํ™˜๊ฒฝ์˜ ์ฐธ์กฐ(ํ•จ์ˆ˜ ๊ฐ์ฒด์˜ ๋‚ด๋ถ€ ์Šฌ๋กฏ [[Environment]]์— ์ €์žฅ๋œ)๊ฐ€ ์ €์žฅ๋œ๋‹ค.

3. ํด๋กœ์ €์™€ ๋ ‰์‹œ์ปฌ ํ™˜๊ฒฝ

์™ธ๋ถ€ ํ•จ์ˆ˜๋ณด๋‹ค ์ค‘์ฒฉ ํ•จ์ˆ˜๊ฐ€ ๋” ์˜ค๋ž˜ ์œ ์ง€๋˜๋Š” ๊ฒฝ์šฐ ์ค‘์ฒฉ ํ•จ์ˆ˜๋Š” ์ด๋ฏธ ์ƒ๋ช… ์ฃผ๊ธฐ๊ฐ€ ์ข…๋ฃŒํ•œ ์™ธ๋ถ€ ํ•จ์ˆ˜์˜ ๋ณ€์ˆ˜๋ฅผ ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋Ÿฌํ•œ ์ค‘์ฒฉ ํ•จ์ˆ˜๋ฅผ ํด๋กœ์ €๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค.

ํด๋กœ์ €์— ๋Œ€ํ•œ MDN์— ์ •์˜๋Š” "ํด๋กœ์ €๋Š” ํ•จ์ˆ˜์™€ ๊ทธ ํ•จ์ˆ˜๊ฐ€ ์„ ์–ธ๋œ ๋ ‰์‹œ์ปฌ ํ™˜๊ฒฝ๊ณผ์˜ ์กฐํ•ฉ์ด๋‹ค." ์—ฌ๊ธฐ์„œ "ํ•จ์ˆ˜๊ฐ€ ์„ ์–ธ๋œ ๋ ‰์‹œ์ปฌ ํ™˜๊ฒฝ"์ด๋ž€ ํ•จ์ˆ˜๊ฐ€ ์ •์˜๋œ ์œ„์น˜์˜ ์Šค์ฝ”ํ”„, ์ฆ‰ ์ƒ์œ„ ์Šค์ฝ”ํ”„๋ฅผ ์˜๋ฏธํ•˜๋Š” ์‹คํ–‰ ์ปจํ…์ŠคํŠธ์˜ ๋ ‰์‹œ์ปฌ ํ™˜๊ฒฝ์„ ๋งํ•œ๋‹ค.

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ๋ชจ๋“  ํ•จ์ˆ˜๋Š” ์ž์‹ ์˜ ์ƒ์œ„ ์Šค์ฝ”ํ”„๋ฅผ ๊ธฐ์–ตํ•œ๋‹ค. ๋ชจ๋“  ํ•จ์ˆ˜๊ฐ€ ๊ธฐ์–ตํ•˜๋Š” ์ƒ์œ„ ์Šค์ฝ”ํ”„๋Š” ํ•จ์ˆ˜๋ฅผ ์–ด๋””์„œ ํ˜ธ์ถœํ•˜๋“  ์ƒ๊ด€์—†์ด ์œ ์ง€๋œ๋‹ค.

๋”ฐ๋ผ์„œ ํ•จ์ˆ˜๋ฅผ ์–ด๋””์„œ ํ˜ธ์ถœํ•˜๋“  ์ƒ๊ด€์—†์ด ํ•จ์ˆ˜๋Š” ์–ธ์ œ๋‚˜ ์ž์‹ ์ด ๊ธฐ์–ตํ•˜๋Š” ์ƒ์œ„ ์Šค์ฝ”ํ”„์˜ ์‹๋ณ„์ž๋ฅผ ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ์‹๋ณ„์ž์— ๋ฐ”์ธ๋”ฉ๋œ ๊ฐ’์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋‹ค.

const x = 1;

// โ‘ 
function outer() {
  const x = 10;
  const inner = function () { console.log(x); }; // โ‘ก
  return inner;
}

// outer ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ์ค‘์ฒฉ ํ•จ์ˆ˜ inner๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
// ๊ทธ๋ฆฌ๊ณ  outer ํ•จ์ˆ˜์˜ ์‹คํ–‰ ์ปจํ…์ŠคํŠธ๋Š” ์‹คํ–‰ ์ปจํ…์ŠคํŠธ ์Šคํƒ์—์„œ ํŒ๋˜์–ด ์ œ๊ฑฐ๋œ๋‹ค.
const innerFunc = outer(); // โ‘ข
innerFunc(); // โ‘ฃ 10

โ‘ข์—์„œ outerํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด outerํ•จ์ˆ˜๋Š” ์ค‘์ฒฉ ํ•จ์ˆ˜inner๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ณ  ์ƒ๋ช… ์ฃผ๊ธฐ๋ฅผ ๋งˆ๊ฐํ•œ๋‹ค. ์ฆ‰, outerํ•จ์ˆ˜์˜ ์‹คํ–‰ ์ปจํ…์ŠคํŠธ๋Š” ์‹คํ–‰ ์ปจํ…์ŠคํŠธ ์Šคํƒ์—์„œ ์ œ๊ฑฐ๋œ๋‹ค.
์ด๋•Œ outerํ•จ์ˆ˜์˜ ์ง€์—ญ ๋ณ€์ˆ˜ x๋˜ํ•œ ์ƒ๋ช… ์ฃผ๊ธฐ๋ฅผ ๋งˆ๊ฐํ•œ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ โ‘ฃ์—์„œ innerํ•จ์ˆ˜ ํ˜ธ์ถœ ๊ฒฐ๊ณผ๋Š” outerํ•จ์ˆ˜์˜ ์ง€์—ญ ๋ณ€์ˆ˜ x์˜ ๊ฐ’์ธ 10์ด๋‹ค. ์ด๋ฏธ ์ƒ๋ช… ์ฃผ๊ธฐ๊ฐ€ ์ข…๋ฃŒ๋˜์–ด ์‹คํ–‰ ์ปจํ…์ŠคํŠธ ์Šคํƒ์—์„œ ์ œ๊ฑฐ๋œ outerํ•จ์ˆ˜์˜ ์ง€์—ญ ๋ณ€์ˆ˜ x๊ฐ€ ๋‹ค์‹œ ๋ถ€ํ™œ์ด๋ผ๋„ ํ•œ๋“ฏ ๋™์ž‘ํ•œ๋‹ค.

1.์ „์—ญ ์ฝ”๋“œ ์‹คํ–‰(outer๊ฐ์ฒด ์ƒ์„ฑ)

2.outerํ•จ์ˆ˜ ํ˜ธ์ถœ(inner๊ฐ์ฒด ์ƒ์„ฑ ๋ฐ ๋ฐ˜ํ™˜)

3.innerFunc ์ „์—ญ ๋ณ€์ˆ˜์— innerํ•จ์ˆ˜ ์ฐธ์กฐ ํ• ๋‹น

outer ํ•จ์ˆ˜์˜ ์‹คํ–‰์ด ์ข…๋ฃŒ๋˜๋ฉด inner ํ•จ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋ฉด์„œ outer ํ•จ์ˆ˜์˜ ์ƒ๋ช… ์ฃผ๊ธฐ๊ฐ€ ์ข…๋ฃŒ ์ฆ‰, outer ํ•จ์ˆ˜์˜ ์‹คํ–‰ ์ปจํ…์ŠคํŠธ๊ฐ€ ์‹คํ–‰ ์ปจํ…์ŠคํŠธ ์Šคํƒ์—์„œ ์ œ๊ฑฐ๋œ๋‹ค.

์ด๋•Œ outer ํ•จ์ˆ˜์˜ ์‹คํ–‰ ์ปจํ…์ŠคํŠธ๋Š” ์‹คํ–‰ ์ปจํ…์ŠคํŠธ ์Šคํƒ์—์„œ ์ œ๊ฑฐ๋˜์ง€๋งŒ outer ํ•จ์ˆ˜์˜ ๋ ‰์‹œ์ปฌ ํ™˜๊ฒฝ๊นŒ์ง€ ์†Œ๋ฉธํ•˜๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค

outer ํ•จ์ˆ˜์˜ ๋ ‰์‹œ์ปฌ ํ™˜๊ฒฝ์€ inner ํ•จ์ˆ˜์˜ [[Environment]] ๋‚ด๋ถ€ ์Šฌ๋กฏ์— ์˜ํ•ด ์ฐธ์กฐ๋˜์–ด ์žˆ๊ณ  inner ํ•จ์ˆ˜๋Š” ์ „์—ญ ๋ณ€์ˆ˜ innerFunc์— ์˜ํ•ด ์ฐธ์กฐ๋˜๊ณ  ์žˆ์œผ๋ฏ€๋กœ ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰์…˜์˜ ๋Œ€์ƒ์ด ๋˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

๊ฐ€๋น„์ง€ ์ปฌ๋ ‰ํ„ฐ๋Š” ๋ˆ„๊ตฐ๊ฐ€๊ฐ€ ์ฐธ์กฐํ•˜๊ณ  ์žˆ๋Š” ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„์„ ํ•จ๋ถ€๋กœ ํ•ด์ œํ•˜์ง€ ์•Š๋Š”๋‹ค.

4.innerFuncํ˜ธ์ถœ๋กœ innerํ•จ์ˆ˜์˜ ๋ ‰์‹œ์ปฌ ํ™˜๊ฒฝ ์ƒ์„ฑ(innerํ•จ์ˆ˜ ๊ฐ์ฒด์˜ [[Environment]]๋‚ด๋ถ€ ์Šฌ๋กฏ ์ฐธ์กฐ)

outer ํ•จ์ˆ˜๊ฐ€ ๋ฐ˜ํ™˜ํ•œ inner ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœ ํ•˜๋ฉด inner ํ•จ์ˆ˜์˜ ์‹คํ–‰ ์ปจํ…์ŠคํŠธ๊ฐ€ ์ƒ์„ฑ๋˜๊ณ  ์‹คํ–‰ ์ปจํ…์ŠคํŠธ ์Šคํƒ์— ํ‘ธ์‹œ๋œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋ ‰์‹œ์ปฌ ํ™˜๊ฒฝ์˜ ์™ธ๋ถ€ ๋ ‰์‹œ์ปฌ ํ™˜๊ฒฝ์— ๋Œ€ํ•œ ์ฐธ์กฐ์—๋Š” inner ํ•จ์ˆ˜ ๊ฐ์ฒด์˜ [[Environment]] ๋‚ด๋ถ€ ์Šฌ๋กฏ์— ์ €์žฅ๋˜์–ด ์žˆ๋Š” ์ฐธ์กฐ๊ฐ’์ด ํ• ๋‹น.

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ๋ชจ๋“  ํ•จ์ˆ˜๋Š” ์ƒ์œ„ ์Šค์ฝ”ํ”„๋ฅผ ๊ธฐ์–ตํ•˜๋ฏ€๋กœ ์ด๋ก ์ ์œผ๋กœ ๋ชจ๋“  ํ•จ์ˆ˜๋Š” ํด๋กœ์ €๋‹ค. ํ•˜์ง€๋งŒ ์ผ๋ฐ˜์ ์œผ๋กœ ๋ชจ๋“  ํ•จ์ˆ˜๋ฅผ ํด๋กœ์ €๋ผ๊ณ  ํ•˜์ง€๋Š” ์•Š๋Š”๋‹ค.

<!DOCTYPE html>
<html>
<body>
  <script>
    function foo() {
      const x = 1;
      const y = 2;

      // ์ผ๋ฐ˜์ ์œผ๋กœ ํด๋กœ์ €๋ผ๊ณ  ํ•˜์ง€ ์•Š๋Š”๋‹ค.
      function bar() {
        const z = 3;

        debugger;
        // ์ƒ์œ„ ์Šค์ฝ”ํ”„์˜ ์‹๋ณ„์ž๋ฅผ ์ฐธ์กฐํ•˜์ง€ ์•Š๋Š”๋‹ค.
        console.log(z);
      }

      return bar;
    }

    const bar = foo();
    bar();
  </script>
</body>
</html>

์ƒ์œ„ ์Šค์ฝ”ํ”„์˜ ์‹๋ณ„์ž x , y๋ฅผ ์ฐธ์กฐํ•˜์ง€ ์•Š์•˜์œผ๋ฏ€๋กœ ํด๋กœ์ €๋ผ ํ•  ์ˆ˜ ์—†๋‹ค.

์ƒ์œ„ ์Šค์ฝ”ํ”„์˜ ์–ด๋–ค ์‹๋ณ„์ž๋„ ์ฐธ์กฐํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ ๋Œ€๋ถ€๋ถ„์˜ ๋ชจ๋˜ ๋ธŒ๋ผ์šฐ์ €๋Š” ์ตœ์ ํ™”๋ฅผ ํ†ตํ•ด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ƒ์œ„ ์Šค์ฝ”ํ”„๋ฅผ ๊ธฐ์–ตํ•˜์ง€ ์•Š๋Š”๋‹ค. ์ฐธ์กฐํ•˜์ง€ ์•Š๋Š” ์‹๋ณ„์ž๋ฅผ ๊ธฐ์–ตํ•˜๋Š” ๊ฒƒ์€ ๋ฉ”๋ชจ๋ฆฌ ๋‚ญ๋น„์ด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

<!DOCTYPE html>
<html>
<body>
  <script>
    function foo() {
      const x = 1;

      // ์ผ๋ฐ˜์ ์œผ๋กœ ํด๋กœ์ €๋ผ๊ณ  ํ•˜์ง€ ์•Š๋Š”๋‹ค.
      // bar ํ•จ์ˆ˜๋Š” ํด๋กœ์ €์˜€์ง€๋งŒ ๊ณง๋ฐ”๋กœ ์†Œ๋ฉธํ•œ๋‹ค.
      function bar() {
        debugger;
        // ์ƒ์œ„ ์Šค์ฝ”ํ”„์˜ ์‹๋ณ„์ž๋ฅผ ์ฐธ์กฐํ•œ๋‹ค.
        console.log(x);
      }
      bar();
    }

    foo();
  </script>
</body>
</html>

์ƒ์œ„ ์Šค์ฝ”ํ”„์˜ ์‹๋ณ„์ž๋ฅผ ์ฐธ์กฐํ•˜๊ณ  ์žˆ์œผ๋ฏ€๋กœ ํด๋กœ์ €๋‹ค. ํ•˜์ง€๋งŒ ์™ธ๋ถ€ ํ•จ์ˆ˜ foo๋ณด๋‹ค ์ค‘์ฒฉ ํ•จ์ˆ˜ bar์˜ ์ƒ๋ช… ์ฃผ๊ธฐ๊ฐ€ ์งง๋‹ค.

์ด๋Ÿฐ ๊ฒฝ์šฐ ์ผ๋ฐ˜์ ์œผ๋กœ ํด๋กœ์ €๋ผ๊ณ  ํ•˜์ง€ ์•Š๋Š”๋‹ค.

<!DOCTYPE html>
<html>
<body>
  <script>
    function foo() {
      const x = 1;
      const y = 2;

      // ํด๋กœ์ €
      // ์ค‘์ฒฉ ํ•จ์ˆ˜ bar๋Š” ์™ธ๋ถ€ ํ•จ์ˆ˜๋ณด๋‹ค ๋” ์˜ค๋ž˜ ์œ ์ง€๋˜๋ฉฐ ์ƒ์œ„ ์Šค์ฝ”ํ”„์˜ ์‹๋ณ„์ž๋ฅผ ์ฐธ์กฐํ•œ๋‹ค.
      function bar() {
        debugger;
        console.log(x);
      }
      return bar;
    }

    const bar = foo();
    bar();
  </script>
</body>
</html>

ํด๋กœ์ €๋Š” ์ค‘์ฒฉ ํ•จ์ˆ˜๊ฐ€ ์ƒ์œ„ ์Šค์ฝ”ํ”„์˜ ์‹๋ณ„์ž๋ฅผ ์ฐธ์กฐํ•˜๊ณ  ์žˆ๊ณ  ์ค‘์ฒฉ ํ•จ์ˆ˜๊ฐ€ ์™ธ๋ถ€ ํ•จ์ˆ˜๋ณด๋‹ค ๋” ์˜ค๋ž˜ ์œ ์ง€๋˜๋Š” ๊ฒฝ์šฐ์— ํ•œ์ •๋˜๋Š” ๊ฒƒ์ด ์ผ๋ฐ˜์ ์ด๋‹ค.

์ƒ์œ„ ์Šคํฌํฌ์˜ x, y ์‹๋ณ„์ž์ค‘์—์„œ x๋งŒ ์ฐธ์กฐ ์ด๋Ÿฐ ๊ฒฝ์šฐ ๋Œ€๋ถ€๋ถ„์˜ ๋ชจ๋˜ ๋ธŒ๋ผ์šฐ์ €๋Š” ์ตœ์ ํ™”๋ฅผ ํ†ตํ•ด ์ƒ์œ„ ์Šค์ฝ”ํ”„์˜ ์‹๋ณ„์ž ์ค‘์—์„œ ํด๋กœ์ €๊ฐ€ ์ฐธ์กฐํ•˜๊ณ  ์žˆ๋Š” ์‹๋ณ„์ž๋งŒ์„ ๊ธฐ์–ตํ•œ๋‹ค.

ํด๋กœ์ €์— ์˜ํ•ด ์ฐธ์กฐ๋˜๋Š” ์ƒ์œ„ ์Šค์ฝ”ํ”„์˜ ๋ณ€์ˆ˜๋ฅผ ์ž์œ  ๋ณ€์ˆ˜๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค.

ํด๋กœ์ €๋ž€ "ํ•จ์ˆ˜๊ฐ€ ์ž์œ  ๋ณ€์ˆ˜์— ๋Œ€ํ•ด ๋‹ซํ˜€์žˆ๋‹ค"๋ผ๋Š” ์˜๋ฏธ๋‹ค. ์ด๋ฅผ ์ข€ ๋” ์•Œ๊ธฐ ์‰ฝ๊ฒŒ ์˜์—ญํ•˜์ง€๋งˆ๋…€ "์ž์œ  ๋ณ€์ˆ˜์— ๋ฌถ์—ฌ์žˆ๋Š” ํ•จ์ˆ˜"๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ๋‹ค.

4. ํด๋กœ์ €์˜ ํ™œ์šฉ

ํด๋กœ์ €๋Š” ์ƒํƒœ๋ฅผ ์•ˆ์ „ํ•˜๊ฒŒ ๋ณ€๊ฒฝํ•˜๊ณ  ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•œ๋‹ค. ๋‹ค์‹œ ๋งํ•ด, ์ƒํƒœ๊ฐ€ ์˜๋„์น˜ ์•Š๊ฒŒ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š๋„๋ก ์ƒํƒœ๋ฅผ ์•ˆ์ „ํ•˜๊ฒŒ ์€๋‹‰ํ•˜๊ณ  ํŠน์ • ํ•จ์ˆ˜์—๊ฒŒ๋งŒ ์ƒํƒœ ๋ณ€๊ฒฝ์„ ํ—ˆ์šฉํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•œ๋‹ค.

4-1). ์ „์—ญ ๋ณ€์ˆ˜๋กœ ๊ด€๋ฆฌ

// ์นด์šดํŠธ ์ƒํƒœ ๋ณ€์ˆ˜
let num = 0;

// ์นด์šดํŠธ ์ƒํƒœ ๋ณ€๊ฒฝ ํ•จ์ˆ˜
const increase = function ( {
  // ์นด์šดํŠธ ์ƒํƒœ๋ฅผ 1๋งŒํผ ์ฆ๊ฐ€์‹œํ‚จ๋‹ค.
  return ++num;
};                                                          

์œ„ ์ฝ”๋“œ๋Š” ์ž˜ ๋™์ž‘ํ•˜์ง€๋งŒ ์˜ค๋ฅ˜๋ฅผ ๋ฐœ์ƒ์‹œํ‚ฌ ๊ฐ€๋Šฅ์„ฑ์„ ๋‚ดํฌํ•˜๊ณ  ์žˆ๋Š” ์ข‹์ง€ ์•Š์€ ์ฝ”๋“œ ๊ทธ ์ด์œ ๋Š” ๋‹ค์Œ์˜ ์ „์ œ์กฐ๊ฑด์ด ์ง€์ผœ์ค˜์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
1. ์นด์šดํŠธ ์ƒํƒœ(num ๋ณ€์ˆ˜์˜ ๊ฐ’)๋Š” increase ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋˜๊ธฐ ์ „๊นŒ์ง€ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š๊ณ  ์œ ์ง€๋˜์–ด์•ผ ํ•œ๋‹ค.
2. ์ด๋ฅผ ์œ„ํ•ด ์นด์šฐํŠธ ์ƒํƒœ(num ๋ณ€์ˆ˜์˜ ๊ฐ’)๋Š” increase ํ•จ์ˆ˜๋งŒ์ด ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•œ๋‹ค.

ํ•˜์ง€๋งŒ num ๋ณ€์ˆ˜๋Š” ์ „์—ญ ๋ณ€์ˆ˜๋กœ ์–ธ์ œ๋“ ์ง€ ๋ˆ„๊ตฌ๋‚˜ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๊ณ  ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋‹ค. ๋”ฐ๋ผ์„œ ์นด์šดํŠธ ์ƒํƒœ๋ฅผ ์•ˆ์ „ํ•˜๊ฒŒ ๋ณ€๊ฒฝํ•˜๊ณ  ์œ ์ง€ํ•˜๊ธฐ์œ„ํ•ด์„œ๋Š” increase ํ•จ์ˆ˜๋งŒ์ด num ๋ณ€์ˆ˜๋ฅผ ์ฐธ์กฐํ•˜๊ณ  ๋ณ€๊ฒฝ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๋Š” ๊ฒƒ์ด ๋ฐ”๋žŒ์งํ•˜๋‹ค.

4-2. ์ง€์—ญ ๋ณ€์ˆ˜๋กœ ๊ด€๋ฆฌ

const increase = function () {
  // ์นด์šดํŠธ ์ƒํƒœ ๋ณ€์ˆ˜
  let num = 0;
  
  // ์นด์šดํŠธ ์ƒํƒœ๋ฅผ 1๋งŒํผ ์ฆ๊ฐ€์‹œํ‚จ๋‹ค.
  retrun ++num;
};

// ์ด์ „ ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•˜์ง€ ๋ชปํ•œ๋‹ค.
console.log(increase()); // 1
console.log(increase()); // 1
console.log(increase()); // 1

์ „์—ญ ๋ณ€์ˆ˜ num์„ increase ํ•จ์ˆ˜์˜ ์ง€์—ญ๋ณ€์ˆ˜๋กœ ๋ณ€๊ฒฝํ•˜์—ฌ ์˜๋„์น˜ ์•Š์€ ์ƒํƒœ ๋ณ€๊ฒฝ์€ ๋ฐฉ์ง€ํ–ˆ๋‹ค.

ํ•˜์ง€๋งŒ increase ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋  ๋•Œ๋งˆ๋‹ค ์ง€์—ญ ๋ณ€์ˆ˜ num์„ ๋‹ค์‹œ ์„ ์–ธ๋˜๊ณ  ์ดˆ๊ธฐํ™”๋œ๋‹ค. ๋‹ค์‹œ๋งํ•ด, ์ƒํƒœ๊ฐ€ ๋ณ€๊ฒฝ๋˜๊ธฐ ์ด์ „ ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•˜์ง€ ๋ชปํ•œ๋‹ค.

4-3. ํด๋กœ์ €

// ์นด์šดํŠธ ์ƒํƒœ ๋ณ€๊ฒฝ ํ•จ์ˆ˜
const increase = (function () {
  // ์นด์šดํŠธ ์ƒํƒœ ๋ณ€์ˆ˜
  let num = 0;
  // ํด๋กœ์ €
  return function () {
    // ์นด์šดํŠธ ์ƒํƒœ๋ฅผ 1๋งŒํผ ์ฆ๊ฐ€์‹œํ‚จ๋‹ค.
    return ++num;
  };
}());

console.log(increase());
console.log(increase());
console.log(increase());

์œ„ ์˜ˆ์ œ๋Š” ํด๋กœ์ €์ด๋‹ค.
์ฆ‰์‹œ ์‹คํ–‰ ํ•จ์ˆ˜๋กœ ํ˜ธ์ถœ๋œ ์ดํ›„ ์†Œ๋ฉธ๋˜๊ณ  ๋ฐ˜ํ™˜ํ•œ ํด๋กœ์ €๋Š” increase๋ณ€์ˆ˜์— ํ• ๋‹น.

ํด๋กœ์ €๋Š” num๋ณ€์ˆ˜๊ฐ€ ์˜๋„์น˜ ํ•œ๊ฒŒ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š๋„๋ก ์•ˆ์ „ํ•˜๊ฒŒ ์€๋‹‰ํ•˜๊ณ  ํŠน์ •ํ•จ์ˆ˜์—๊ฒŒ๋งŒ ์ƒํƒœ ๋ณ€๊ฒฝ์„ ํ—ˆ์š”ํ•˜์—ฌ ์ƒํƒœ๋ฅผ ์•ˆ์ „ํ•˜๊ฒŒ ๋ณ€๊ฒฝํ•˜๊ณ  ์œ ์ง€ํ•˜๊ธฐ์œ„ํ•ด ์‚ฌ์šฉ๋œ๋‹ค.

4-4. ๊ฐ์†Œ ๊ธฐ๋Šฅ ์ถ”๊ฐ€(ํด๋กœ์ €)

const counter = (function () {
  // ์นด์šดํŠธ ์ƒํƒœ ๋ณ€์ˆ˜
  let num = 0;
  
  // ํด๋กœ์ €์ธ ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ–๋Š” ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
  // ๊ฐ์ฒด ๋ฆฌํ„ฐ๋Ÿด์€ ์Šค์ฝ”ํ”„๋ฅผ ๋งŒ๋“ค์ง€ ์•Š๋Š”๋‹ค.
  // ๋”ฐ๋ผ์„œ ์•„๋ž˜ ๋ฉ”์„œ๋“œ๋“ค์˜ ์ƒ์œ„ ์Šค์ฝ”ํ”„๋Š” ์ฆ‰์‹œ ์‹คํ–‰ ํ•จ์ˆ˜์˜ ๋ ‰์‹œ์ปฌ ํ™˜๊ฒฝ์ด๋‹ค.
  return {
    // num: 0, // ํ”„๋กœํผํ‹ฐ๋Š” punlicํ•˜๋ฏ€๋กœ ์€๋‹‰๋˜์ง€ ์•Š๋Š”๋‹ค.
    increase() retrun ++num;
  	},
    decrease() {
    	return num > 0 ? --num : 0;
  	}
	};
}();

console.log(counter.increase()); // 1
console.log(counter.increase()); // 2

console.log(counter.decrease()); // 1
console.log(counter.decrease()); // 0

4-5. ์ƒ์„ฑ์ž ํ•จ์ˆ˜ (ํด๋กœ์ €)

const Counter = (function () {
  // 
  let num = 0;
  
  function Counter() {
    // this.num = 0; // ํ”„๋กœํผํ‹ฐ๋Š” publicํ•˜๋ฏ€๋กœ ์€๋‹‰๋˜์ง€ ์•Š๋Š”๋‹ค.
  }
  
  Counter.prototype.increase = function () {
    ruturn  ++num;
  };
  
  Counter.prototype.decrease = function () {
    return num > 0 > --num : 0;
  };
  
  return Counter;
}());

const counter = new Counter();

console.log(counter.increase()); // 1
console.log(counter.increase()); // 2

console.log(counter.decrease()); // 1
console.log(counter.decrease()); // 0

increase, decrease ๋ฉ”์„œ๋“œ๋Š” ํ”„๋กœํ† ํƒ€์ž… ๋ฉ”์„œ๋“œ์ด๋‹ค.
์ด ๋ฉ”์„œ๋“œ๋“ค์ด ํ‰๊ฐ€๋˜์–ด ํ•จ์ˆ˜ ๊ฐ์ฒด๊ฐ€ ์ƒ์„ฑ๋  ๋•Œ ์‹คํ–‰ ์ค‘์ธ ์‹คํ–‰ ์ปจํ…์ŠคํŠธ๋Š” ์ฆ‰์‹œ ์‹คํ–‰ ํ•จ์ˆ˜์˜ ์‹คํ–‰ ์ปจํ…์ŠคํŠธ์ด๋‹ค. ๋”ฐ๋ผ์„œ increase, decrease๋ฉ”์„œ๋“œ๋Š” ์ฆ‰์‹œ ์‹คํ–‰ ํ•จ์ˆ˜์˜ ์‹คํ–‰ ์ปจํ…์ŠคํŠธ์˜ ๋ ‰์‹œ์ปฌ ํ™˜๊ฒฝ์„ ๊ธฐ์–ตํ•˜๋Š” ํด๋กœ์ € ์ด๋‹ค.

๋‹ค์‹œ ๋งํ•˜๋ฉด num๋ณ€์ˆ˜์˜ ๊ฐ’์€ increase์™€ decrease๋ฉ”์„œ๋“œ๋งŒ์ด ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋‹ค.

4-6. ๊ณ ์ฐจํ•จ์ˆ˜ ํ™œ์šฉํ•œ ํด๋กœ์ €

โ“ ๊ณ ์ฐจ ํ•จ์ˆ˜๋ž€?

๋ณด์กฐ ํ•จ์ˆ˜๋ฅผ ์ธ์ž๋กœ ์ „๋‹ฌ๋ฐ›๊ณ  ํ•จ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜

// ํ•จ์ˆ˜๋ฅผ ์ธ์ˆ˜๋กœ ์ „๋‹ฌ๋ฐ›๊ณ  ํ•จ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ณ ์ฐจํ•จ์ˆ˜
// ์ด ํ•จ์ˆ˜๋Š” ์นด์šดํŠธ ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•œ ์ž์œ  ๋ณ€์ˆ˜ counter๋ฅผ ๊ธฐ์–ตํ•˜๋Š” ํด๋กœ์ €๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
function makeCounter(aux) {
  // ์นด์šดํŠธ ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•œ ์žฅ์œ  ๋ณ€์ˆ˜
  let counter = 0;
  
  // ํด๋กœ์ €๋ฅผ ๋ฐ˜ํ™˜
  return function () {
    // ์ธ์ˆ˜๋กœ ์ „๋‹ฌ๋ฐ›์€ ๋ณด์กฐ ํ•จ์ˆ˜์— ์ƒํƒœ ๋ณ€๊ฒฝ์„ ์œ„์ž„ํ•œ๋‹ค.
    counter = aux(counter);
    return counter;
  };
}

// ๋ณด์กฐ ํ•จ์ˆ˜
function increase(n) {
  return ++n;
}

// ๋ณด์กฐ ํ•จ์ˆ˜
function decrease(n) {
  return --n;
}

// ํ•จ์ˆ˜๋กœ ํ•จ์ˆ˜๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.
// makeCounter ํ•จ์ˆ˜๋Š” ๋ณด์กฐ ํ•จ์ˆ˜๋ฅผ ์ธ์ˆ˜๋กœ ์ „๋‹ฌ๋ฐ›์•„ ํ•จ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
const increaser = makeCounter(increase); // โ‘ 
console.log(increaser()); // 1
console.log(increaser()); // 2

// increaser ํ•จ์ˆ˜์™€๋Š” ๋ณ„๊ฐœ์˜ ๋…๋ฆฝ๋œ ๋ ‰์‹œ์ปฌ ํ™˜๊ฒฝ์„ ๊ฐ–๊ธฐ ๋•Œ๋ฌธ์— ์นด์šดํ„ฐ ์ƒํƒœ๊ฐ€ ์—ฐ๋™ํ•˜์ง€ ์•Š๋Š”๋‹ค.
const decreser = makeCounter(decrease);
console.log(decreaser());
console.log(decreaser());

makeCounter ํ•จ์ˆ˜๋Š” ๋ณด์กฐ ํ•จ์ˆ˜๋ฅผ ์ธ์ž๋กœ ์ „๋‹ฌ๋ฐ›๊ณ  ํ•จ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ณ ์ฐจ ํ•จ์ˆ˜
makeCounter ํ•จ์ˆ˜๊ฐ€ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜๋Š” ํ•จ์ˆ˜๋Š” counter ๋ณ€์ˆ˜๋ฅผ ๊ธฐ์–ตํ•˜๋Š” ํด๋กœ์ €๋‹ค.

! ์ฃผ์˜ํ•ด์•ผ ํ•  ๊ฒƒ์€ makeCounter ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•ด ํ•จ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•  ๋•Œ ๋ฐ˜ํ™˜๋œ ํ•จ์ˆ˜๋Š” ์ž์‹ ๋งŒ์˜ ๋…๋ฆฝ๋œ ๋ ‰์‹œ์ปฌ ํ™˜๊ฒฝ์„ ๊ฐ–๋Š”๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. ์ด๋Š” ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ๊ทธ๋•Œ๋งˆ๋‹ค ์ƒˆ๋กœ์šด makeCounter ํ•จ์ˆ˜ ์‹คํ–‰ ์ปจํ…์ŠคํŠธ์˜ ๋ ‰์‹œ์ปฌ ํ™˜๊ฒฝ์ด ์ƒ์„ฑ๋˜๊ธฐ ๋•Œ๋ฌธ.


์œ„ ์˜ˆ์ œ์—์„œ ์ „์—ญ ๋ณ€์ˆ˜ increaser์™€ decreaser์— ํ• ๋‹น๋œ ํ•จ์ˆ˜๋Š” ๊ฐ๊ฐ ์ž์‹ ๋งŒ์˜ ๋…๋ฆฝ๋œ ๋ ‰์‹œ์ปฌ ํ™˜๊ฒฝ์„ ๊ฐ–๊ธฐ ๋•Œ๋ฌธ์— ์นด์šดํŠธ๋ฅผ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•œ ์ž์œ  ๋ณ€์ˆ˜ counter๋ฅผ ๊ณต์œ ํ•˜์ง€ ์•Š์•„ ์นด์šดํ„ฐ ์ฆ๊ฐ์ด ์—ฐ๋™๋˜์ง€ ์•Š๋Š”๋‹ค.

๋”ฐ๋ผ์„œ ๋…๋ฆณ๋œ ์นด์šดํ„ฐ๊ฐ€ ์•„๋‹ˆ๋ผ ์—ฐ๋™ํ•˜์—ฌ ์ฆ๊ฐ์ด ๊ฐ€๋Šฅํ•œ ์นด์šดํ„ฐ๋ฅผ ๋งŒ๋“ค๋ ค๋ฉด ๋ ‰์‹œ์ปฌํ™˜๊ฒฝ์„ ๊ณต์œ ํ•˜๋Š” ํด๋กœ์ €๋ฅผ ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค. ์ด๋ฅผ ์œ„ํ•ด์„œ๋Š” makeCounterํ•จ์ˆ˜๋ฅผ ๋‘ ๋ฒˆ ํ˜ธ์ถœํ•˜์ง€ ๋ง์•„์•ผ ํ•œ๋‹ค.

4-6-1. ๋…๋ฆฝ์ด ์•„๋‹Œ ๊ณต์œ ๋œ ํด๋กœ์ €

// ํ•จ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ณ ์ฐจ ํ•จ์ˆ˜
// ์ด ํ•จ์ˆ˜๋Š” ์นด์šดํŠธ ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•œ ์ž์œ  ๋ณ€์ˆ˜ counter๋ฅผ ๊ธฐ์–ตํ•˜๋Š” ํด๋กœ์ €๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
const counter = (function () {
  // ์นด์šดํŠธ ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•œ ์ž์œ  ๋ณ€์ˆ˜
  let counter = 0;
  
  // ํ•จ์ˆ˜๋ฅผ ์ธ์ˆ˜๋กœ ์ „๋‹ฌ๋ฐ›๋Š” ํด๋กœ์ €๋ฅผ ๋ฐ˜ํ™˜
  return function (aux) {
    // ์ธ์ˆ˜๋กœ ์ „๋‹ฌ๋ฐ›์€ ๋ณด์กฐ ํ•จ์ˆ˜์— ์ƒํƒœ ๋ณ€๊ฒฝ์„ ์œ„์ž„ํ•œ๋‹ค.
    counter = aux(counter)
    return counter;
  };
}());

// ๋ณด์กฐ ํ•จ์ˆ˜
function increase(n) {
  return ++n;
}

// ๋ณด์กฐ ํ•จ์ˆ˜
function decrease(n) {
  return --n;
}

// ๋ณด์กฐ ํ•จ์ˆ˜๋ฅผ ์ „๋‹ฌํ•˜์—ฌ ํ˜ธ์ถœ
console.log(counter(increase)); // 1
console.log(counter(increase)); // 2

// ์ž์œ  ๋ณ€์ˆ˜๋ฅผ ๊ณต์œ ํ•œ๋‹ค.
console.log(counter(decrease)); // 1
console.log(counter(decrease)); // 0

5. ์บก์Šํ™”์™€ ์ •๋ณด ์€๋‹‰

์บก์Šํ™”๋Š” ๊ฐ์ฒด์˜ ์ƒํƒœ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ํ”„๋กœํผํ‹ฐ์™€ ํ”„๋กœํผํ‹ฐ๋ฅผ ์ฐธ์กฐํ•˜๊ณ  ์กฑํ•  ์ˆ˜ ์žˆ๋Š” ๋™์ž‘์ธ ๋ฉ”์„œ๋“œ๋ฅผ ํ•˜๋‚˜๋กœ ๋ฌถ๋Š” ๊ฒƒ์„ ๋งํ•œ๋‹ค. ์บก์Šํ™”๋Š” ๊ฐ์ฒด์˜ ํŠน์ • ํ”„๋กœํผํ‹ฐ๋‚˜ ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ์ถœ ๋ชฉ์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๊ธฐ๋„ ํ•˜๋Š”๋ฐ ์ด๋ฅผ ์ •๋ณด ์€๋‹‰์ด๋ผ ํ•œ๋‹ค.

์ •๋ณด ์€๋‹‰์€ ์™ธ๋ถ€์— ๊ณต๊ฐœํ•  ํ•„์š”๊ฐ€ ์—†๋Š” ๊ตฌํ˜„์˜ ์ผ๋ถ€๋ฅผ ์™ธ๋ถ€์— ๊ณต๊ฐœ๋˜์ง€ ์•Š๋„๋ก ๊ฐ์ถ”์–ด ์ ์ ˆ์น˜ ๋ชปํ•œ ์ ‘๊ทผ์œผ๋กœ๋ถ€ํ„ฐ ๊ฐ์ฒด์˜ ์ƒํƒœ๊ฐ€ ๋ณ€๊ฒฝ๋˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•ด ์ •๋ณด๋ฅผ ๋ณดํ˜ธํ•˜๊ณ , ๊ฐ์ฒด ๊ฐ„์˜ ์ƒํ˜ธ ์˜์กด์„ฑ, ์ฆ‰, ๊ฒฐํ•ฉ๋„๋ฅผ ๋‚ฎ์ถ”๋Š” ํšจ๊ณผ๊ฐ€ ์žˆ๋‹ค.

๋Œ€๋ถ€๋ถ„ ๊ฐ์ฒด์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด๋Š” ํด๋ž˜์Šค๋ฅผ ์ •์˜ํ•˜๊ณ  ํด๋ž˜์Šค๋ฅผ ๊ตฌ์„ฑํ•˜๋Š” ํ”„๋กœํผํ‹ฐ์™€ ๋ฉ”์„œ๋“œ์— ๋Œ€ํ•˜์—ฌ public private protected ๊ฐ™์€ ์ ‘๊ทผ ์ œํ•œ์ž๋ฅผ ์„ ์–ธํ•˜์—ฌ ๊ณต๊ฐœ ๋ฒ”์œ„๋ฅผ ํ•œ์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” public private protected ๊ฐ™์€ ์ ‘๊ทผ ์ œํ•œ์ž๋ฅผ ์ œ๊ณตํ•˜์ง€ ์•Š๋Š”๋‹ค. ๋”ฐ๋ผ์„œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๊ฐ์ฒด์˜ ๋ชจ๋“  ํ”„๋กœํผํ‹ฐ์™€ ๋ฉ”์„œ๋“œ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ์™ธ๋ถ€์— ๊ณต๊ฐœ๋˜์–ด ์ž‡๋‹ค. ์ฆ‰, ๊ฐ์ฒด์˜ ๋ชจ๋“  ํ”„๋กœํผํ‹ฐ์™€ ๋ฉ”์„œ๋“œ๋Š ๊ธฐ๋ณธ์ ์œผ๋กœ publicํ•˜๋‹ค.

function Person(name, age) {
  this.name = name; // public
  let _age = age; // private
  
  // ์ธ์Šคํ„ด์Šค ๋ฉ”์„œ๋“œ
  this.sayHi = function() {
    console.log(`Hi! My name is ${this.name}. I am ${_age}.`);
  };
}

const me = new Person('Lee', 20)
me.sayHi(); // Hi! My name is Lee. I am 20
console.log(me.name); // Lee
console.log(me._age); // undefined
            
const you = new Person('Kim', 30);
you.sayHi();
console.log(you.name); // Kim
console.log(you._age); // undefined

์œ„ ์˜ˆ์ œ name ํ”„๋กœํผํ‹ฐ๋Š” ํ˜„์žฌ ์™ธ๋ถ€๋กœ ๊ณต๊ฐœ๋˜์–ด ์žˆ์–ด ์ž์œ ๋กญ๊ฒŒ ์ฐธ์กฐ ๋ณ€๊ฒฝ ๊ฐ€๋Šฅ ์ฆ‰, nameํ”„๋กœํผํ‹ฐ๋Š” publiceํ•˜๋‹ค.

ํ•˜์ง€๋งŒ _age๋ณ€์ˆ˜๋Š” Person์ƒ์„ฑ์ž ํ•จ์ˆ˜์˜ ์ง€์—ญ ๋ณ€์ˆ˜์ด๋ฏ€๋กœ Person์ƒ์„ฑ์ž ํ•จ์ˆ˜ ์™ธ๋ถ€์—์„œ ์ฐธ์กฐํ•˜๊ฑฐ๋‚˜ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†๋‹ค. ์ฆ‰, _age ๋ณ€์ˆ˜๋Š” privateํ•˜๋‹ค.

sayHi ๋ฉ”์„œ๋“œ ํ”„๋กœํ† ํƒ€์ž…์œผ๋กœ ๋ณ€๊ฒฝํ•˜์—ฌ sayHi ๋ฉ”์„œ๋“œ์˜ ์ค‘๋ณต ์ƒ์„ฑ์„ ๋ฐฉ์ง€

function Person(name, age) {
  this.name = name; // public
  let _age = age; // private
}

// ํ”„๋กœํ† ํƒ€์ž… ๋ฉ”์„œ๋“œ
Person.prototype.sayHi = function () {
  // Person ์ƒ์„ฑ์ž ํ•จ์ˆ˜์˜ ์ง€์—ญ ๋ณ€์ˆ˜ _age๋ฅผ ์ฐธ์กฐํ•  ์ˆ˜ ์—†๋‹ค.
  console.log(`Hi! My name is ${this.name}. I am ${_age}.`);
};

์ง€์—ญ ๋ณ€์ˆ˜ _age๋ฅผ ์ฐธ์กฐํ•  ์ˆ˜ ์—†๋Š” ๋ฌธ์ œ ํ•ด๊ฒฐ.

const Person = (function () {
  let _age  = 0; // private
  
  // ์ƒ์„ฑ์ž ํ•จ์ˆ˜
  function Person(name, age) {
    this.name = name; // public
    _age = age;
  }
  
  // ํ”„๋กœํ† ํƒ€์ž… ๋ฉ”์„œ๋“œ
  Person.prototype.sayHi = function () {
    console.log(`Hi My name is ${this.name}. I am ${_age}.`)
  };
  
  // ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜
  return Person;
}());

์œ„ ํŒจํ„ด ์‚ฌ์šฉํ•˜๋ฉด public private protected ๊ฐ™์€ ์ ‘๊ธ‰ ์ œํ•œ์ž๋ฅผ ์ œ๊ณตํ•˜์ง€ ์•Š๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ๋„ ์ •๋ณด ์€๋‹‰์ด ๊ฐ€๋Šฅํ•œ ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ธ๋‹ค.

Person ์ƒ์„ฑ์ž ํ•จ์ˆ˜์™€ sayHi ๋ฉ”์„œ๋“œ๋Š” ์ด๋ฏธ ์ข…๋ฃŒ๋˜์–ด ์†Œ๋ฉธํ•œ ์ฆ‰์‹œ ์‹คํ–‰ ํ•จ์ˆ˜์˜ ์ง€์—ญ ๋ณ€์ˆ˜ _age๋ฅผ ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ๋Š” ํด๋กœ์ €๋‹ค.

ํ•˜์ง€๋งŒ ์œ„ ์˜ˆ์ œ๋„ ์™„๋ฒฝํ•˜์ง„ ์•Š๋‹ค.
Person์ƒ์„ฑ์ž ํ•จ์ˆ˜๊ฐ€ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•  ๊ฒฝ์šฐ _age๋ณ€์ˆ˜์˜ ์ƒํƒœ๊ฐ€ ์œ ์ง€๋˜์ง€ ์•Š๋Š”๋‹ค

const me = new Person('Lee', 20);
me.sayHi(); // Hi! My name is Lee. I am 20

const you = new Person('Kim', 30);
you.sayHi(); // Hi! My name is Kim. I am 30

// _age ๋ณ€์ˆ˜ ๊ฐ’์ด ๋ณ€๊ฒฝ๋œ๋‹ค!
me.sayHi(); // Hi! My name is Lee I am 30.

์ฆ‰์‹œ ์‹คํ–‰ ํ•จ์ˆ˜๋กœ ๋ฐ˜ํ™˜๋œ ๋™์ผํ•œ ์ƒ์œ„ ์Šค์ฝ”ํ”„๋ฅผ ์ฐธ์กฐํ•˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ.

6. ์ž์ฃผ ๋ฐœ์ƒํ•˜๋Š” ์‹ค์ˆ˜

// ์ž์ฃผ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ์‹ค์ˆ˜
var func = [];

for (var i = 0; i <3; i++); }
	funcs[i] = function () { return i }; // โ‘ 
}

for (var j = 0; j func.length; j++) {
  console.log(funcs[j]()); // โ‘ก

0 1 2๋ฅผ ๋ฐ˜ํ™˜ํ•  ๊ฒƒ์œผ๋กœ ๊ธฐ๋Œ€ํ–ˆ์ง€๋งŒ ๊ฒฐ๊ณผ๋Š” 3 3 3์ด ๋ฐ˜ํ™˜๋˜์—ˆ๋‹ค.
for๋ฌธ์˜ ๋ณ€์ˆ˜ ์„ ์–ธ๋ฌธ์—์„œ var ํ‚ค์›Œ๋“œ๋กœ ์„ ์–ธํ•œ i ๋ณ€์ˆ˜๋Š” ๋ธ”๋ก๋ ˆ๋ฒจ ์Šค์ฝ”ํ”„๊ฐ€ ์•„๋‹Œ ํ•จ์ˆ˜ ์Šค์ฝ”ํ”„ ์ฆ‰, ์ „์—ญ ๋ณ€์ˆ˜๋กœ ์„ ์–ธ๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์— i๊ฐ’์„ ์ „๋‹ฌํ•˜์—ฌ๋„ ํ˜ธ์ถœํ•˜๋Š” ์‹œ์ ์—์„œ i๊ฐ’์€ 3์ด๊ธฐ ๋•Œ๋ฌธ์— ์›ํ•˜๋Š” ๊ฒฐ๊ณผ๊ฐ’์„ ์–ป์ง€ ๋ชปํ•œ๋‹ค.

// ์œ„ ์˜ˆ์ œ๋ฅผ ํด๋กœ์ €๋กœ ๊ณ ์น˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.
var funcs = [];

for (var i = 0; i < 3; i++){
  funcs[i] = (function (id) { // โ‘ 
    return function () {
      return id;
    };
  }(i));
}

for (var j = 0; j < funcs.length; j++) {
  console.log(funcs[j]()); // โ‘ก
}

โ‘ ์—์„œ ์ฆ‰์‹œ ์‹คํ–‰ ํ•จ์ˆ˜๋Š” ์ „์—ญ ๋ณ€์ˆ˜ i์— ํ˜„์žฌ ํ• ๋‹น๋˜์–ด ์žˆ๋Š” ๊ฐ’์„ ์ธ์ˆ˜๋กœ ์ „๋‹ฌ๋ฐ›์•„ ๋งค๊ฐœ๋ณ€์ˆ˜ id์— ํ• ๋‹นํ•œ ํ›„ ์ค‘์ฒฉ ํ•จ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ณ  ์ข…๋ฃŒ

์ด๋•Œ ์ฆ‰์‹œ ์‹คํ–‰ ํ•จ์ˆ˜์˜ ๋งค๊ฐœ๋ณ€์ˆ˜ id๋Š” ์ฆ‰์‹œ ์‹คํ–‰ ํ•จ์ˆ˜๊ฐ€ ๋ฐ˜ํ™˜ํ•œ ์ค‘์ฒฉ ํ•จ์ˆ˜์˜ ์ƒ์œ„ ์Šค์ฝ”ํ”„์— ์กด์žฌ. ์ฆ‰์‹œ ์‹คํ–‰ ํ•จ์ˆ˜๊ฐ€ ๋ฐ˜ํ™˜ํ•œ ์ค‘์ฒฉ ํ•จ์ˆ˜๋Š” ์ž์ด์‹ ์˜ ์ƒ์œ„ ์Šค์ฝ”ํ”„(์ฆ‰์‹œ ์‹คํ–‰ ํ•จ์ˆ˜์˜ ๋ ‰์‹œ์ปฌ ํ™˜๊ฒฝ)๋ฅผ ๊ธฐ์–ตํ•˜๋Š” ํด๋กœ์ง€์ด๊ณ , ๋งค๊ฐœ๋ณ€์ˆ˜ id๋Š” ์ฆ‰์‹œ ์‹คํ–‰ ํ•จ์ˆ˜๊ฐ€ ๋ฐ˜ํ™˜ํ•œ ์ค‘์ฒฉ ํ•จ์ˆ˜์— ๋ฌถ์—ฌ์žˆ๋Š” ์ž์œ  ๋ณ€์ˆ˜๊ฐ€ ๋˜์–ด ๊ทธ ๊ฐ’ ์œ ์ง€

// let ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด ๋ฌธ์ œํ•ด๊ฒฐ
const funcs = [];

for (let i = 0; i < 3; i++) {
  funcs[i] = function () return i
}

for (let i = 0; i < func.length; i++) {
  console.log(funcs[i]()); // 0 1 2
}

์œ„ ์˜ˆ์ œ์—์„œ for๋ฌธ์˜ ํ•จ์ˆ˜์— ์ƒ์œ„ ์Šค์ฝ”ํ”„๋Š” for๋ฌธ์˜ ์ฝ”๋“œ ๋ธ”๋ก์ด ๋ฐ˜๋ณต ์‹คํ–‰๋  ๋•Œ๋งˆ๋‹ค ์ƒ์„ฑ๋œ for๋ฌธ ์ฝ”๋“œ ๋ธ”๋ก์˜ ์ƒˆ๋กœ์šด ๋ ‰์‹œ์ปฌ ํ™˜๊ฒฝ์ด๋‹ค.

let ํ‚ค์›Œ๋“œ๋Š” ๋ธ”๋ก ๋ ˆ๋ฒจ ์Šค์ฝ”ํ”„์ด๊ธฐ ๋•Œ๋ฌธ์— for๋ฌธ์ด ๋ฐ˜๋ณต๋  ๋•Œ๋งˆ๋‹ค ์ƒˆ๋กœ์šด ๋ ‰์‹œ์ปฌ ํ™˜๊ฒฝ์„ ์ƒ์„ฑํ•œ๋‹ค.

๋ฐ˜๋ณต๋ฌธ์˜ ์ฝ”๋“œ ๋ธ”๋ก ๋‚ด๋ถ€์—์„œ ํ•จ์ˆ˜๋ฅผ ์ •์˜ํ•  ๋•Œ ์˜๋ฏธ๊ฐ€ ์žˆ๋‹ค. ์ƒˆ๋กœ์šด ๋ ‰์‹œ์ปฌ ํ™˜๊ฒฝ์€ ์•„๋ฌด๋„ ์ฐธ์กฐํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰์…˜์˜ ๋Œ€์‚ฐ์ด ๋œ๋‹ค.

๋˜ ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์œผ๋กœ ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๊ธฐ๋ฒ•์ธ ๊ณ ์ฐจ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค.

// ์š”์†Œ๊ฐ€ 3๊ฐœ์ธ ๋ฐฐ์—ด์„ ์ƒ์„ฑํ•˜๊ณ  ๋ฐฐ์—ด์˜ ์ธ๋ฑ์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ์š”์†Œ๋กœ ์ถ”๊ฐ€ํ•œ๋‹ค.
// ๋ฐฐ์—ด์˜ ์š”์†Œ๋กœ ์ถ”๊ฐ€๋œ ํ•จ์ˆ˜๋“ค์€ ๋ชจ๋‘ ํด๋กœ์ €๋‹ค.
const funcs = Array.from(new Array(3), (_, i) => () i); // (3) [f, f, f]

// ๋ฐฐ์—ด์˜ ์š”์†Œ๋กœ ์ถ”๊ฐ€๋œ ํ•จ์ˆ˜๋“ค์„ ์ˆœ์ฐจ์ ์œผ๋กœ ํ˜ธ์ถœํ•œ๋‹ค.
funcs.forEach(f => console.log(f())); // 0 1 2
post-custom-banner

0๊ฐœ์˜ ๋Œ“๊ธ€