Skip to content

Latest commit

ย 

History

History
757 lines (540 loc) ยท 24.4 KB

24__study_heeso.md

File metadata and controls

757 lines (540 loc) ยท 24.4 KB

24์žฅ ํด๋กœ์ €


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

MDN "ํด๋กœ์ €๋Š” ํ•จ์ˆ˜์™€ ๊ทธ ํ•จ์ˆ˜๊ฐ€ ์„ ์–ธ๋œ ๋ ‰์‹œ์ปฌ ํ™˜๊ฒฝ๊ณผ์˜ ์กฐํ•ฉ์ด๋‹ค."

์ œ์ผ ๋จผ์ € ์ดํ•ดํ•ด์•ผ ํ•  ํ•ต์‹ฌ ํ‚ค์›Œ๋“œ๋Š” "ํ•จ์ˆ˜๊ฐ€ ์„ ์–ธ๋œ ๋ ‰์‹œ์ปฌ ํ™˜๊ฒฝ"์ด๋‹ค.

์˜ˆ์ œ 24-01
const x = 1;

function outerFunc() {
  const x = 10;

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

  innerFunc();
}

outerFunc();

7๋ฒˆ์งธ ์ค„ ์ฝ˜์†”์—์„œ 10์ด ๋‚˜์˜จ ์ด์œ  : ์ž์‹ ์ด ์ •์˜๋œ ํ™˜๊ฒฝ( ์ƒ์œ„์Šค์ฝ”ํ”„ )๋ฅผ ๊ธฐ์–ตํ•œ๋‹ค.

ํ•จ์ˆ˜์—์„œ ๋‚ด๋ถ€๋Š” ์™ธ๋ถ€ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ์™ธ๋ถ€์—์„œ ๋‚ด๋ถ€ ๊ฐ’์œผ๋กœ๋Š” ์ ‘๊ทผํ•  ์ˆ˜ ์—†๋‹ค.

outerFunc ํ•จ์ˆ˜ ๋‚ด๋ถ€์—์„œ ์ค‘์ฒฉ ํ•จ์ˆ˜ innerFunc๊ฐ€ ์ •์˜, ํ˜ธ์ถœ๋˜์—ˆ๋‹ค. ์ค‘์ฒฉ ํ•จ์ˆ˜ innerFunc์˜ ์ƒ์œ„ ์Šค์ฝ”ํ”„๋Š” outerFunc์ด๋‹ค. ์ค‘์ฒฉ ํ•จ์ˆ˜ innerFunc ๋‚ด๋ถ€์—์„œ ์ž์‹ ์„ ํฌํ•จํ•˜๊ณ  ์žˆ๋Š” ์™ธ๋ถ€ ํ•จ์ˆ˜ outerFunc์˜ x ๋ณ€์ˆ˜์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค.

์˜ˆ์ œ 24-02
const x = 1;

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

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

outerFunc();

outerFunc ๋‚ด๋ถ€์— ์žˆ๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ๋”ฐ๋กœ ์žˆ๋‹ค. innerFunc์˜ ์ƒ์œ„ ์Šค์ฝ”ํ”„๋Š” ์ „์—ญ์ด๊ธฐ ๋•Œ๋ฌธ์— 9๋ฒˆ ์ค„ ์ฝ˜์†”์˜ ๊ฒฐ๊ณผ๊ฐ’์€ 1์ด๋‹ค.


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

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

์˜ˆ์ œ 24-03
const x = 1;

function foo() {
  const x = 10;
  bar();
} // ์ „์—ญ ํ•จ์ˆ˜

function bar() {
  console.log(x);
} // ์ „์—ญ ํ•จ์ˆ˜

foo(); // ?
bar(); // ?

๊ฒฐ๊ณผ ๊ฐ’์€ ๋ฌด์—‡์ผ๊นŒ?

์ด์œ ๋Š” ๋ฌด์—‡์ผ๊นŒ?

bar ํ•จ์ˆ˜์˜ ์ƒ์œ„ ์Šค์ฝ”ํ”„๋Š”? => ์ „์—ญ foo ํ•จ์ˆ˜๋Š” bar ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰์‹œํ‚ค๋Š” ๊ฐ’์ด๊ธฐ ๋•Œ๋ฌธ์— bar ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰์‹œํ‚จ ๊ฐ’์ด ๋‚˜์˜จ๋‹ค.

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

ํ˜ธ๋ž‘์ด๊ฐ€ ์šฐ์ฃผ๋กœ ๋‚ฉ์น˜๋˜์–ด์„œ๋„ ๊ธฐ์–ต ํ•  ํ˜ธ๋ž‘์ด์˜ ๊ณ ํ–ฅ์€ ํ˜ธ๋ž‘์ด๊ฐ€ ํƒœ์–ด๋‚œ ์‹œ์ ์—์„œ์˜ ์œ„์น˜์— ์˜ํ•ด ๊ฒฐ์ •๋œ๋‹ค.
= ํ˜ธ๋ž‘์ด๋Š” ์ง€๊ตฌ์—์„œ ํƒœ์–ด๋‚ฌ๊ธฐ ๋•Œ๋ฌธ์— ํ˜ธ๋ž‘์ด์˜ ๊ณ ํ–ฅ์€ ์ง€๊ตฌ์ด๋‹ค.


24.2 ํ•จ์ˆ˜ ๊ฐ์ฒด์˜ ๋‚ด๋ถ€ ์Šฌ๋กฏ

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

ํ˜ธ๋ž‘์ด๋Š” ์–ด๋–ค ํ–‰์„ฑ์— ๊ฐ€๋”๋ผ๋„ ํ•ญ์ƒ ์ž์‹ ์˜ ๊ณ ํ–ฅ์ธ ์ง€๊ตฌ(์ƒ์œ„์Šค์ฝ”ํ”„) ๋ฅผ ๊ธฐ์–ตํ•œ๋‹ค.

์˜ˆ์ œ 24-04
const x = 1;

function foo() {
  const x = 10;

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

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

foo(); // ?
bar(); // ?

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

์˜ˆ์ œ 24-05
const x = 1;

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

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

innerFunc ์˜ ์‹คํ–‰ ๊ฐ’์ด 10์ด ๋‚˜์˜ค๋Š” ๊ณผ์ • : outer ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœ (3) => ์ค‘์ฒฉ ํ•จ์ˆ˜ inner๋ฅผ ๋ฐ˜ํ™˜ => ์ƒ๋ช… ์ฃผ๊ธฐ ๋งˆ๊ฐ => outer ํ•จ์ˆ˜ ์‹คํ–‰ ์ข…๋ฃŒ => ์‹คํ–‰ ์ปจํ…์ŠคํŠธ์—์„œ ์ œ๊ฑฐ => outer ํ•จ์ˆ˜์˜ ์ง€์—ญ๋ณ€์ˆ˜ x(10) ์˜ ์ƒ๋ช… ์ฃผ๊ธฐ ๋งˆ๊ฐ ์ƒ๋ช… ์ฃผ๊ธฐ๊ฐ€ ๋งˆ๊ฐ๋˜์–ด ๋ณ€์ˆ˜ x(10)์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ด ์—†์–ด ๋ณด์ด์ง€๋งŒ, ์‹คํ–‰ ๊ฒฐ๊ณผ๋Š” 10์ด๋‹ค.

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

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

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

์›” E ( ๊ฐ€๋น„์ง€์ปฌ๋ ‰ํ„ฐ )๊ฐ€ ํ˜ธ๋ž‘์ด๋ฅผ ๋‚ฉ์น˜ํ•ด ์ง€๊ตฌ์—์„œ ํ˜ธ๋ž‘์ด๊ฐ€ ์—†์–ด์ง€๋”๋ผ๋„ = ์‹คํ–‰ ์ปจํ…์ŠคํŠธ ์Šคํƒ์—์„œ ์‹คํ–‰ ์ปจํ…์ŠคํŠธ๊ฐ€ ์ œ๊ฑฐ๋˜๋”๋ผ๋„
ํ˜ธ๋ž‘์ด๋Š” ์ž์‹ ์˜ ๊ณ ํ–ฅ์ธ ์ง€๊ตฌ(์ƒ์œ„์Šค์ฝ”ํ”„)์˜ ํ™˜๊ฒฝ์„ ๊ธฐ์–ตํ•œ๋‹ค.

๋” ์˜ค๋ž˜ ์ƒ์กดํ•œ ์ค‘์ฒฉ ํ•จ์ˆ˜๋Š” ์™ธ๋ถ€ ํ•จ์ˆ˜์˜ ์ƒ์กด ์—ฌ๋ถ€(์‹คํ–‰ ์ปจํ…์ŠคํŠธ์˜ ์ƒ์กด ์—ฌ๋ถ€)์™€ ์ƒ๊ด€์—†์ด ์ž์‹ ์ด ์ •์˜๋œ ์œ„์น˜์— ์˜ํ•ด ๊ฒฐ์ •๋œ ์ƒ์œ„ ์Šค์ฝ”ํ”„๋ฅผ ๊ธฐ์–ตํ•œ๋‹ค. ์ค‘์ฒฉ ํ•จ์ˆ˜ inner ๋‚ด๋ถ€์—์„œ๋Š” ์ƒ์œ„ ์Šค์ฝ”ํ”„๋ฅผ ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์ƒ์œ„ ์Šค์ฝ”ํ”„์˜ ์‹๋ณ„์ž๋ฅผ ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ๊ณ  ์‹๋ณ„์ž์˜ ๊ฐ’์„ ๋ณ€๊ฒฝํ•  ์ˆ˜๋„ ์žˆ๋‹ค.


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

ํ•˜์ง€๋งŒ ์ผ๋ฐ˜์ ์œผ๋กœ ๋ชจ๋“  ํ•จ์ˆ˜๋ฅผ ํด๋กœ์ €๋ผ๊ณ  ํ•˜์ง€ ์•Š๋Š”๋‹ค.

์˜ˆ์ œ 24-06
<!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>

bar ํ•จ์ˆ˜๋Š” ํด๋กœ์ €์ผ๊นŒ?

bar ํ•จ์ˆ˜๊ฐ€ ํด๋กœ์ €๊ฐ€ ์•„๋‹Œ ์ด์œ ๋Š” ๋ญ˜๊นŒ? => ์ƒ์œ„ ์Šค์ฝ”ํ”„์˜ ์‹๋ณ„์ž๋ฅผ ์ฐธ์กฐํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์—

์˜ˆ์ œ 24-07
<!DOCTYPE html>
<html>
<body>
  <script>
    function foo() {
      const x = 1;

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

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

bar ํ•จ์ˆ˜๋Š” ํด๋กœ์ €์ผ๊นŒ?

๋„ค

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

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

์ค‘์ฒฉ ํ•จ์ˆ˜ bar๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ํด๋กœ์ €๋ผ๊ณ  ํ•˜์ง€ ์•Š๋Š”๋‹ค.

์˜ˆ์ œ 24-08
<!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>

bar ํ•จ์ˆ˜๋Š” ํด๋กœ์ €์ผ๊นŒ?

๋„ค

bar ํ•จ์ˆ˜๊ฐ€ ํด๋กœ์ €์ธ ์ด์œ ๋Š”?

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

์ž์œ ๋ณ€์ˆ˜ : ํด๋กœ์ €์— ์˜ํ•ด ์ฐธ์กฐ๋˜๋Š” ์ƒ์œ„ ์Šค์ฝ”ํ”„์˜ ๋ณ€์ˆ˜ = foo ํ•จ์ˆ˜์˜ x ๋ณ€์ˆ˜

clousre ๋ž€ ํ•จ์ˆ˜๊ฐ€ ์ž์œ  ๋ณ€์ˆ˜์— ๋Œ€ํ•ด ๋‹ซํ˜€์žˆ๋‹ค (closed) ๋ผ๋Š” ์˜๋ฏธ์ด๋‹ค.

์ž์œ  ๋ณ€์ˆ˜์— ๋ฌถ์—ฌ์žˆ๋Š” ํ•จ์ˆ˜

ํ˜ธ๋ž‘์ด๊ฐ€ ์ง€๊ตฌ๋ฅผ ๊ธฐ์–ตํ•˜๊ณ  ๊ธฐ์–ตํ•œ ๋‚ด์šฉ์„ ์จ๋จน์„๋•Œ๊ฐ€ ์ง„์ •ํ•œ ํด๋กœ์ € ! Alt text


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

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

num ๋ณ€์ˆ˜๋Š” ์•ˆ์ „ํ•˜๊ฒŒ ๋ณ€๊ฒฝํ•˜๊ณ  ์œ ์ง€ํ•ด์•ผ ํ•  ์ƒํƒœ๋ผ๋Š” ๊ฒƒ์„ ๊ธฐ์–ตํ•˜๊ณ  ์•„๋ž˜์˜ ์˜ˆ์ œ๋ฅผ ์‚ดํŽด๋ด…์‹œ๋‹ค.

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

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

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

์œ„ ์ฝ”๋“œ๊ฐ€ ๋ฐ”๋ฅด๊ฒŒ ๋™์ž‘ํ•˜๊ธฐ ์œ„ํ•ด ์ง€์ผœ์ ธ์•ผ ํ•˜๋Š” ์กฐ๊ฑด

  1. ์นด์šดํŠธ ์ƒํƒœ (num ๋ณ€์ˆ˜์˜ ๊ฐ’)์€ increase ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋˜๊ธฐ ์ „๊นŒ์ง€ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š๊ณ  ์œ ์ง€๋˜์–ด์•ผ ํ•œ๋‹ค.
  2. ์นด์šดํŠธ ์ƒํƒœ (num ๋ณ€์ˆ˜์˜ ๊ฐ’)์€ increase ํ•จ์ˆ˜๋งŒ์ด ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•œ๋‹ค.

ํ•˜์ง€๋งŒ ์นด์šดํŠธ ์ƒํƒœ๋Š” ์ „์—ญ ๋ณ€์ˆ˜ ์ด๊ธฐ ๋•Œ๋ฌธ์— ๋ˆ„๊ตฌ๋‚˜ ์ ‘๊ทผ, ๋ณ€๊ฒฝ ๊ฐ€๋Šฅ

๐Ÿคฏ ์˜๋„์น˜ ์•Š๊ฒŒ ์ƒํƒœ๊ฐ€ ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ์Œ

์˜ˆ์ œ 24-10
// ์นด์šดํŠธ ์ƒํƒœ ๋ณ€๊ฒฝ ํ•จ์ˆ˜
const increase = function () {
  // ์นด์šดํŠธ ์ƒํƒœ ๋ณ€์ˆ˜
  let num = 0;

  // ์นด์šดํŠธ ์ƒํƒœ๋ฅผ 1๋งŒํผ ์ฆ๊ฐ€ ์‹œํ‚จ๋‹ค.
  return ++num;
};

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

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

num๋ณ€์ˆ˜์˜ ์ƒํƒœ๋Š” increase ํ•จ์ˆ˜๋งŒ์ด ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋‹ค.

console.log ์˜ ๊ฒฐ๊ณผ๋Š” ๋ฌด์—‡์ผ๊นŒ? : ๋ชจ๋‘ 1

console.log ์˜ ๊ฒฐ๊ณผ๊ฐ’์ด ๋ชจ๋‘ 1์ธ ์ด์œ ๋Š” ๋ฌด์—‡์ผ๊นŒ? : increase ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋  ๋•Œ๋งˆ๋‹ค ์ง€์—ญ ๋ณ€์ˆ˜ num์ด ๋‹ค์‹œ ์„ ์–ธ, 0์œผ๋กœ ์ดˆ๊ธฐํ™”๋˜๊ธฐ ๋•Œ๋ฌธ

๐Ÿคฏ ์ด์ „ ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•˜์ง€ ๋ชปํ•จ

์˜ˆ์ œ 24-11
// ์นด์šดํŠธ ์ƒํƒœ ๋ณ€๊ฒฝ ํ•จ์ˆ˜
const increase = (function () {
  // ์นด์šดํŠธ ์ƒํƒœ ๋ณ€์ˆ˜
  let num = 0;

  // ํด๋กœ์ €
  return function () {
    // ์นด์šดํŠธ ์ƒํƒœ๋ฅผ 1๋งŒํผ ์ฆ๊ฐ€ ์‹œํ‚จ๋‹ค.
    return ++num;
  };
}());

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

์œ„ ์˜ˆ์ œ์—์„œ๋Š” ์ด์ „ ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ๋„๋ก ํด๋กœ์ €๋ฅผ ์‚ฌ์šฉํ•ด๋ณด์•˜๋‹ค.

์ฆ‰์‹œ ์‹คํ–‰ ํ•จ์ˆ˜๊ฐ€ ๋ฐ˜ํ™˜ํ•œ ํด๋กœ์ €๋Š” ์นด์šดํŠธ ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•œ ์ž์œ  ๋ณ€์ˆ˜ num ์„ ์–ธ์ œ ์–ด๋””์„œ ํ˜ธ์ถœํ•˜๋“ ์ง€ ์ฐธ์กฐํ•˜๊ณ  ๋ณ€๊ฒฝ ํ•  ์ˆ˜ ์žˆ๋‹ค.

ํด๋กœ์ €๋Š” ์ƒํƒœ state ๊ฐ€ ์˜๋„์น˜ ์•Š๊ฒŒ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š๋„๋ก ์•ˆ์ „ํ•˜๊ฒŒ ์€๋‹‰ํ•˜๊ณ  ํŠน์ • ํ•จ์ˆ˜์—๊ฒŒ๋งŒ ์ƒํƒœ ๋ณ€๊ฒฝ์„ ํ—ˆ์šฉํ•˜์—ฌ ์ƒํƒœ๋ฅผ ์•ˆ์ „ํ•˜๊ฒŒ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•œ๋‹ค.
์˜ˆ์ œ 24-12
const counter = (function () {
  // ์นด์šดํŠธ ์ƒํƒœ ๋ณ€์ˆ˜
  let num = 0;

  // ํด๋กœ์ €์ธ ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ–๋Š” ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
  // ๊ฐ์ฒด ๋ฆฌํ„ฐ๋Ÿด์€ ์Šค์ฝ”ํ”„๋ฅผ ๋งŒ๋“ค์ง€ ์•Š๋Š”๋‹ค.
  // ๋”ฐ๋ผ์„œ ์•„๋ž˜ ๋ฉ”์„œ๋“œ๋“ค์˜ ์ƒ์œ„ ์Šค์ฝ”ํ”„๋Š” ์ฆ‰์‹œ ์‹คํ–‰ ํ•จ์ˆ˜์˜ ๋ ‰์‹œ์ปฌ ํ™˜๊ฒฝ์ด๋‹ค.
  return {
    // num: 0, // ํ”„๋กœํผํ‹ฐ๋Š” publicํ•˜๋ฏ€๋กœ ์€๋‹‰๋˜์ง€ ์•Š๋Š”๋‹ค.
    increase() {
      return ++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

์นด์šดํŠธ ์ƒํƒœ๋ฅผ ๊ฐ์†Œ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋„๋ก ๋ฐœ์ „์‹œํ‚จ ์ฝ”๋“œ์ด๋‹ค.

increase, decrease ๋ฉ”์„œ๋“œ๋“ค์˜ ์ƒ์œ„ ์Šค์ฝ”ํ”„๋Š” ์ฆ‰์‹œ ์‹คํ–‰ ํ•จ์ˆ˜์˜ ๋ ‰์‹œ์ปฌ ํ™˜๊ฒฝ์ด๋‹ค.

increase, decrease ๋ฉ”์„œ๋“œ๊ฐ€ ์–ธ์ œ ์–ด๋””์„œ ํ˜ธ์ถœ๋˜๋“  ์ƒ๊ด€์—†์ด increase, decrease ํ•จ์ˆ˜๋Š” ์ฆ‰์‹œ ์‹คํ–‰ ํ•จ์ˆ˜์˜ ์Šค์ฝ”ํ”„์˜ ์‹๋ณ„์ž๋ฅผ ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ๋‹ค.

์˜ˆ์ œ 24-13
const Counter = (function () {
  // โ‘  ์นด์šดํŠธ ์ƒํƒœ ๋ณ€์ˆ˜
  let num = 0;

  function Counter() {
    // this.num = 0; // โ‘ก ํ”„๋กœํผํ‹ฐ๋Š” publicํ•˜๋ฏ€๋กœ ์€๋‹‰๋˜์ง€ ์•Š๋Š”๋‹ค.
  }

  Counter.prototype.increase = function () {
    return ++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 ๋Š” ๋ชจ๋‘ ์ฆ‰์‹œ ์‹คํ–‰ ํ•จ์ˆ˜ ์‹คํ–‰ ์ปจํ…์ŠคํŠธ์˜ ๋ ‰์‹œ์ปฌ ํ™˜๊ฒฝ์„ ๊ธฐ์–ตํ•˜๋Š” ํด๋กœ์ €์ด๋‹ค.


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

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

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

  // ํด๋กœ์ €๋ฅผ ๋ฐ˜ํ™˜ : ์ž์‹ ์ด ์ƒ์„ฑ๋์„ ๋•Œ์˜ ๋ ‰์‹œ์ปฌ ํ™˜๊ฒฝ์ธ
  // makeCounter ํ•จ์ˆ˜์˜์Šค์ฝ”ํ”„์— ์†ํ•œ counter ๋ณ€์ˆ˜๋ฅผ ๊ธฐ์–ตํ•œ๋‹ค.
  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 decreaser = makeCounter(decrease); // โ‘ก
console.log(decreaser()); // -1
console.log(decreaser()); // -2

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

โ‘  makeCounter ํ•จ์ˆ˜ ํ˜ธ์ถœ - makeCounter ํ•จ์ˆ˜์˜ ์‹คํ–‰ ์ปจํ…์ŠคํŠธ ์ƒ์„ฑ - ํ•จ์ˆ˜ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ๋ฐ˜ํ™˜ - ์†Œ๋ฉธ

makeCounter ํ•จ์ˆ˜์˜ ์‹คํ–‰ ์ปจ์ผ์ŠคํŠธ๋Š” ์†Œ๋ฉธ๋˜์ง€๋งŒ ๋ ‰์‹œ์ปฌ ํ™˜๊ฒฝ์€ ์ฐธ์กฐ๋˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์†Œ๋ฉธ๋˜์ง€ ์•Š๋Š”๋‹ค.

โ‘ก ๋„ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์‹คํ–‰๋˜๊ณ , ์ฐธ์กฐ๋œ ํ™˜๊ฒฝ์€ ์†Œ๋ฉธ๋˜์ง€ ์•Š๋Š”๋‹ค.

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

์˜ˆ์ œ 24-15
// ํ•จ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ณ ์ฐจ ํ•จ์ˆ˜
// ์ด ํ•จ์ˆ˜๋Š” ์นด์šดํŠธ ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•œ ์ž์œ  ๋ณ€์ˆ˜ 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

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

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

์ฆ‰์‹œ ์‹คํ–‰ ํ•จ์ˆ˜ ๋‚ด๋ถ€์—์„œ ์ƒ์„ฑ๋œ ๋‹จ์ผํ•œ ํด๋กœ์ €๋งŒ์„ ์‚ฌ์šฉํ•˜์—ฌ ์นด์šดํ„ฐ ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•œ๋‹ค. ๊ฐ™์€ ํด๋กœ์ €์— ๋Œ€ํ•ด ์—ฌ๋Ÿฌ ๋ฒˆ ํ˜ธ์ถœํ•˜๋Š” ๊ฒฝ์šฐ, ๋ณด์กฐ ํ•จ์ˆ˜์— ์˜ํ•ด ๋ณ€๊ฒฝ๋œ ์นด์šดํ„ฐ ๊ฐ’์ด ๊ณ„์†ํ•ด์„œ ์œ ์ง€๋œ๋‹ค.


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

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

์ •๋ณด ์€๋‹‰ : ๊ฐ์ฒด์˜ ํŠน์ • ํ”„๋กœํผํ‹ฐ๋‚˜ ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ์ถ”๋Š” ๊ฒƒ

์บก์Šํ™” ํ•˜๋Š” ์ด์œ  : 1. ๊ฐ์ฒด ๊ฐ„์˜ ์ƒํ˜ธ ์˜์กด์„ฑ = ๊ฒฐํ•ฉ๋„๋ฅผ ๋‚ฎ์ถ˜๋‹ค. : 2. ์™ธ๋ถ€์— ๊ตฌํ˜„์˜ ์ผ๋ถ€๋ฅผ ๊ณต๊ฐœ๋˜์ง€ ์•Š๋„๋ก ๊ฐ์ถ”์–ด ์ ์ ˆ์น˜ ๋ชปํ•œ ์ ‘๊ทผ์œผ๋กœ๋ถ€ํ„ฐ ๊ฐ์ฒด์˜ ์ƒํƒœ๊ฐ€ ๋ณ€๊ฒฝ๋˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•ด ์ •๋ณด๋ฅผ ๋ณดํ˜ธํ•œ๋‹ค.

๊ฐ์ฒด์˜ ๋ชจ๋“  ํ”„๋กœํผํ‹ฐ์™€ ๋ฉ”์„œ๋“œ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ public ํ•˜๋‹ค.

์˜ˆ์ œ 24-16
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(); // Hi! My name is Kim. I am 30.
console.log(you.name); // Kim
console.log(you._age); // undefined

name ํ”„๋กœํผํ‹ฐ๋Š” ์ƒ์„ฑ์ž ํ•จ์ˆ˜ ๋‚ด๋ถ€์—์„œ ์ธ์Šคํ„ด์Šค ๊ฐ์ฒด์— ๋™์ ์œผ๋กœ ์†์„ฑ์„ ์ถ”๊ฐ€ํ•˜๋Š” ๋ฐฉ์‹์ด๊ณ , public ํ•ด์„œ ์ž์œ ๋กญ๊ฒŒ ์ฐธ์กฐ, ๋ณ€๊ฒฝ ๊ฐ€๋Šฅํ•˜๋‹ค.

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

์˜ˆ์ œ 24-17
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}.`);
};

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

Person.prototype.sayHi ๋ฉ”์„œ๋“œ ๋‚ด์—์„œ Person ์ƒ์„ฑ์ž ํ•จ์ˆ˜์˜ ์ง€์—ญ ๋ณ€์ˆ˜ _age๋ฅผ ์ฐธ์กฐํ•  ์ˆ˜ ์—†๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

์˜ˆ์ œ 24-18
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;
}());

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(); // Hi! My name is Kim. I am 30.
console.log(you.name); // Kim
console.log(you._age); // undefined

์ฆ‰์‹œ ์‹คํ–‰ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Person ์ƒ์„ฑ์ž ํ•จ์ˆ˜์™€ Person.prototype.sayHi ๋ฉ”์„œ๋“œ๋ฅผ ํ•˜๋‚˜์˜ ํ•จ์ˆ˜ ๋‚ด์— ๋ชจ์€ ์ฝ”๋“œ์ด๋‹ค.

Person.prototype.sayHi๋Š” ์ฆ‰์‹œ ์‹คํ–‰ ํ•จ์ˆ˜๊ฐ€ ์ข…๋ฃŒ๋œ ์ดํ›„ ํ˜ธ์ถœ๋œ๋‹ค.

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

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

์˜ˆ์ œ 24-19
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.

์ƒˆ๋กœ์šด Person ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•  ๋•Œ๋งˆ๋‹ค _age ๊ฐ’์ด ๋ณ€๊ฒฝ๋œ๋‹ค. ๋งˆ์ง€๋ง‰์œผ๋กœ ์ƒ์„ฑ๋œ ์ธ์Šคํ„ด์Šค์˜ ๋‚˜์ด (_age)๊ฐ€ ์ด์ „ ๋ชจ๋“  ์ธ์Šคํ„ด์Šค์˜ ๋‚˜์ด๋กœ ์„ค์ •๋œ๋‹ค.

_age๋ณ€์ˆ˜๊ฐ€ ๋ชจ๋“  ์ธ์Šคํ„ด์Šค ๊ฐ„์— ๊ณต์œ ๋˜์–ด์„œ ๋งˆ์ง€๋ง‰์œผ๋กœ ์ƒ์„ฑ๋œ you ๊ฐ์ฒด์˜ ๋‚˜์ด(30)๊ฐ€ ์ด์ „์— ๋งŒ๋“ค์–ด์ง„ me ๊ฐ์ฒด์˜ ๋‚˜์ด(20)๋ฅผ ๋ฎ์–ด์“ด ๊ฒƒ์ด๋‹ค.

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ์ •๋ณด ์€๋‹‰์„ ์™„์ „ํ•˜๊ฒŒ ์ง€์›ํ•˜์ง€ ์•Š๋Š”๋‹ค. ์ธ์Šคํ„ด์Šค ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ž์œ  ๋ณ€์ˆ˜๋ฅผ ํ†ตํ•ด ํ‰๋‚ด ๋‚ผ ์ˆ˜์€ ์žˆ์ง€๋งŒ ํ”„๋กœํ† ํƒ€์ž… ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค.

ํด๋ž˜์Šค์— private ํ•„๋“œ๋ฅผ ์ •์˜ํ•  ์ˆ˜ ์žˆ๋Š” ์ƒˆ๋กœ์šด ํ‘œ์ค€ ์‚ฌ์–‘์ด ์ œ์•ˆ๋˜์–ด ์žˆ๋‹ค. 25.7.4์ ˆ์—์„œ ์ž์„ธํžˆ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.


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

์˜ˆ์ œ 24-20
var funcs = [];

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

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

์–ด๋–ค ๊ฐ’์ด ์ถœ๋ ฅ๋ ๊นŒ์š”? 3, 3, 3

์šฐ๋ฆฌ๊ฐ€ ์˜ˆ์ƒํ•œ ๊ฒฐ๊ณผ๋Š”? 0, 1, 2

๋ฌธ์ œ์˜ ์›์ธ์ด ๋ฌด์—‡์ผ๊นŒ์š”? ํด๋กœ์ €์™€ ๋ณ€์ˆ˜ ์Šค์ฝ”ํ”„

โ‘  ์—์„œ ์ต๋ช… ํ•จ์ˆ˜๊ฐ€ ์ƒ์„ฑ๋  ๋•Œ ๊ทธ ํ•จ์ˆ˜๋Š” i ์— ๋Œ€ํ•œ ์ฐธ์กฐ๋ฅผ ์œ ์ง€ํ•œ๋‹ค. for ๋ฃจํ”„๊ฐ€ ๋๋‚œ ํ›„์˜ i ๊ฐ’์€ 3์ด๋‹ค. funcs ๋ฐฐ์—ด ์•ˆ์˜ ๋ชจ๋“  ํ•จ์ˆ˜๋“ค์ด ๋™์ผํ•œ i ( 3 )๋ฅผ ์ฐธ์กฐํ•˜๊ฒŒ ๋˜๋ฏ€๋กœ ๋ชจ๋“  ํ•จ์ˆ˜ ํ˜ธ์ถœ ๊ฒฐ๊ณผ๊ฐ€ 3์ด ๋œ๋‹ค.

์˜ˆ์ œ 24-21
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 ๊ฐ’์„ ๊ฐ€์ง€๋„๋ก ํ•œ๋‹ค.

  1. โ‘ ์—์„œ ๊ฐ ๋ฐ˜๋ณต๋งˆ๋‹ค ์ฆ‰์‹œ ์‹คํ–‰ ํ•จ์ˆ˜ ํ‘œํ˜„์‹์ด ํ˜ธ์ถœ๋œ๋‹ค.
  2. ์ด ํ•จ์ˆ˜๋Š” ๋‹ค์‹œ ๋‚ด๋ถ€์— ์žˆ๋Š” ์ต๋ช…ํ•จ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
  3. ๋ฐ˜ํ™˜๋œ ํ•จ์ˆ˜๊ฐ€ ๊ฐ๊ฐ์˜ funcs[i] ์— ์ €์žฅ๋œ๋‹ค.
  • ๋ฐ˜ํ™˜๋œ ์ต๋ช…ํ•จ์ˆ˜๊ฐ€ ์ฆ‰์‹œ ์‹คํ–‰ ํ•จ์ˆ˜์˜ ์Šค์ฝ”ํ”„์—์„œ ์ƒ์„ฑ๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์—, ํ•ด๋‹น ์Šค์ฝ”ํ”„ ๋‚ด๋ถ€์˜ ๋ณ€์ˆ˜์ธ id๋ฅผ ๊ณ„์† ์ฐธ์กฐํ•˜๊ฒŒ ๋œ๋‹ค. = ํด๋กœ์ €๊ฐ€ ํ˜•์„ฑ๋œ๋‹ค.
  1. funcs[i]์— ์ €์žฅ๋œ ํ•จ์ˆ˜๋Š” ์ž์‹ ๋งŒ์˜ ๊ณ ์œ ํ•œ id๋ฅผ ๊ฐ€์ง€๊ฒŒ ๋œ๋‹ค.
  2. ์›๋ž˜ ๊ธฐ๋Œ€ํ•œ ๊ฒฐ๊ณผ์ธ '0', '1', '2' ์ถœ๋ ฅ

let ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋Š” ํ™˜๊ฒฝ์—์„œ for ๋ฃจํ”„์™€ ํด๋กœ์ €๋ฅผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•  ๋•Œ ๋ฐœ์ƒํ•˜๋Š” ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.

์˜ˆ์ œ 24-22
const funcs = [];

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

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

๊ทธ๋ƒฅ let ํ‚ค์›Œ๋“œ๋ฅผ ์“ฐ๋ฉด ๊ฐ„๋‹จํ•˜๊ฒŒ ํ•ด๊ฒฐ ๊ฐ€๋Šฅํ•˜๋‹ค.

  1. โ‘  ์—์„œ, ๊ฐ ๋ฐ˜๋ณต๋งˆ๋‹ค let i = 0; ๊ตฌ๋ฌธ์— ์˜ํ•ด ์ƒˆ๋กœ์šด i ๋ณ€์ˆ˜๊ฐ€ ์„ ์–ธ๋˜๊ณ  ์ดˆ๊ธฐํ™”๋œ๋‹ค. ์ด๋•Œ let ํ‚ค์›Œ๋“œ๋Š” ๋ธ”๋ก ์Šค์ฝ”ํ”„(block scope)๋ฅผ ๊ฐ€์ง€๋ฏ€๋กœ, ๊ฐ ๋ฐ˜๋ณต๋งˆ๋‹ค ์ƒˆ๋กœ์šด ์Šค์ฝ”ํ”„๊ฐ€ ํ˜•์„ฑ๋ฉ๋‹ˆ๋‹ค.
  2. ์ต๋ช… ํ•จ์ˆ˜ function () { return i; }๊ฐ€ ์ƒ์„ฑ๋˜์–ด funcs[i] ์œ„์น˜์— ์ €์žฅ๋œ๋‹ค. ์ด ํ•จ์ˆ˜๋Š” ์ž์‹ ์„ ์ƒ์„ฑํ•œ ์Šค์ฝ”ํ”„์˜ ๋ณ€์ˆ˜์ธ i์— ๋Œ€ํ•œ ์ฐธ์กฐ๋ฅผ ์œ ์ง€ํ•œ๋‹ค. = ํด๋กœ์ €๊ฐ€ ํ˜•์„ฑ๋œ๋‹ค.
  3. ๊ฐ ๋ฐ˜๋ณต๋งˆ๋‹ค ์ƒˆ๋กญ๊ฒŒ ์„ ์–ธ๋œ i ๋•Œ๋ฌธ์— ๊ฐ๊ฐ์˜ ํด๋กœ์ €(์ต๋ช…ํ•จ์ˆ˜)๋Š” ์„œ๋กœ ๋‹ค๋ฅธ i๋ฅผ ์ฐธ์กฐํ•˜๊ฒŒ ๋œ๋‹ค.
  4. ์›๋ž˜ ๊ธฐ๋Œ€ํ•œ ๊ฒฐ๊ณผ์ธ '0', '1', '2' ์ถœ๋ ฅ

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

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

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

ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๊ธฐ๋ฒ•์ธ ๊ณ ์ฐจ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•๋„ ์žˆ๋‹ค. ์•„์ง ์‚ดํŽด๋ณด์ง€ ์•Š์€ ๋‚ด์šฉ์ด๋‹ˆ ์•Œ์•„๋งŒ ๋‘๋Š”๊ฒŒ ์ข‹๊ฒ ๋‹ค.!!