Language/JavaScript

[JS] ๐Ÿ“š ํด๋กœ์ € (Closure) ๊ฐœ๋… ์™„๋ฒฝ ์ •๋ฆฌ

์ธํŒŒ_ 2021. 9. 27. 07:58

ํด๋กœ์ €-์ •๋ฆฌ

ํด๋กœ์ €(closure) ๋ž€?

ํด๋กœ์ €๋Š” ๋ฐ˜ํ™˜๋œ ๋‚ด๋ถ€ํ•จ์ˆ˜๊ฐ€ ์ž์‹ ์ด ์„ ์–ธ๋์„ ๋•Œ์˜ ํ™˜๊ฒฝ(Lexical environment)์ธ ์Šค์ฝ”ํ”„๋ฅผ ๊ธฐ์–ตํ•˜์—ฌ, ๋งŒ์ผ ์ž์‹ ์ด ์„ ์–ธ๋์„ ๋•Œ์˜ ํ™˜๊ฒฝ(์Šค์ฝ”ํ”„) ๋ฐ–์—์„œ ํ˜ธ์ถœ๋˜์–ด๋„ ์Šค์ฝ”ํ”„์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ํ•จ์ˆ˜๋ฅผ ๋งํ•œ๋‹ค.

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

outerFunc(); // 10
  1. โ€‹ํ•จ์ˆ˜ outerFunc ๋‚ด์—์„œ ๋‚ด๋ถ€ํ•จ์ˆ˜ innerFunc๊ฐ€ ์„ ์–ธ๋˜๊ณ  ํ˜ธ์ถœ๋˜์—ˆ๋‹ค.
  2. ์ด๋•Œ ๋‚ด๋ถ€ํ•จ์ˆ˜ innerFunc๋Š” ์ž์‹ ์„ ํฌํ•จํ•˜๊ณ  ์žˆ๋Š” ์™ธ๋ถ€ํ•จ์ˆ˜ outerFunc์˜ ๋ณ€์ˆ˜ x์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค.
  3. ์ด๋Š” ํ•จ์ˆ˜ innerFunc๊ฐ€ ํ•จ์ˆ˜ outerFunc์˜ ๋‚ด๋ถ€์— ์„ ์–ธ๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

โ€‹์Šค์ฝ”ํ”„๋Š” ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ๊ฐ€ ์•„๋‹ˆ๋ผ ํ•จ์ˆ˜๋ฅผ ์–ด๋””์— ์„ ์–ธํ•˜์˜€๋Š”์ง€์— ๋”ฐ๋ผ ๊ฒฐ์ •๋œ๋‹ค.

์ด๋ฅผ ๋ ‰์‹œ์ปฌ ์Šค์ฝ”ํ•‘(Lexical scoping)๋ผ ํ•œ๋‹ค.

โ€‹

์œ„ ์˜ˆ์ œ์˜ ํ•จ์ˆ˜ innerFunc๋Š” ํ•จ์ˆ˜ outerFunc์˜ ๋‚ด๋ถ€์—์„œ ์„ ์–ธ๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ํ•จ์ˆ˜ innerFunc์˜ ์ƒ์œ„ ์Šค์ฝ”ํ”„๋Š” ํ•จ์ˆ˜ outerFunc์ด๋‹ค.

๋”ฐ๋ผ์„œ ํ•จ์ˆ˜ innerFunc๊ฐ€ ํ•จ์ˆ˜ outerFunc์˜ ๋‚ด๋ถ€์— ์„ ์–ธ๋œ ๋‚ด๋ถ€ํ•จ์ˆ˜์ด๋ฏ€๋กœ ํ•จ์ˆ˜ innerFunc๋Š” ์ž์‹ ์ด ์†ํ•œ ๋ ‰์‹œ์ปฌ ์Šค์ฝ”ํ”„(์ „์—ญ, ํ•จ์ˆ˜ outerFunc, ์ž์‹ ์˜ ์Šค์ฝ”ํ”„)๋ฅผ ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ๋‹ค.

๋งŒ์ผ ํ•จ์ˆ˜ innerFunc๊ฐ€ ์ „์—ญ์— ์„ ์–ธ๋˜์—ˆ๋‹ค๋ฉด ํ•จ์ˆ˜ innerFunc์˜ ์ƒ์œ„ ์Šค์ฝ”ํ”„๋Š” ์ „์—ญ ์Šค์ฝ”ํ”„๊ฐ€ ๋œ๋‹ค.
โ€‹์ด๊ฒƒ์„ ์‹คํ–‰ ์ปจํ…์ŠคํŠธ ์˜ ๊ด€์ ์—์„œ ์„ค๋ช…ํ•ด๋ณด๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.
 1) innerFunc ํ•จ์ˆ˜ ์Šค์ฝ”ํ”„(ํ•จ์ˆ˜ ์ž์‹ ์˜ ์Šค์ฝ”ํ”„๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ํ™œ์„ฑ ๊ฐ์ฒด) ๋‚ด์—์„œ ๋ณ€์ˆ˜ x๋ฅผ ๊ฒ€์ƒ‰ํ•œ๋‹ค. ๊ฒ€์ƒ‰์ด ์‹คํŒจํ•˜์˜€๋‹ค.
 2) innerFunc ํ•จ์ˆ˜๋ฅผ ํฌํ•จํ•˜๋Š” ์™ธ๋ถ€ ํ•จ์ˆ˜ outerFunc์˜ ์Šค์ฝ”ํ”„(ํ•จ์ˆ˜ outerFunc์˜ ์Šค์ฝ”ํ”„๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ํ•จ์ˆ˜ outerFunc์˜ ํ™œ์„ฑ ๊ฐ์ฒด)์—์„œ ๋ณ€์ˆ˜ x๋ฅผ ๊ฒ€์ƒ‰ํ•œ๋‹ค. ๊ฒ€์ƒ‰์ด ์„ฑ๊ณตํ•˜์˜€๋‹ค.

โ€‹

์ด๋ฒˆ์—๋Š” ๋‚ด๋ถ€ํ•จ์ˆ˜ innerFunc๋ฅผ ํ•จ์ˆ˜ outerFunc ๋‚ด์—์„œ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ๋ฐ˜ํ™˜ํ•˜๋„๋ก ๋ณ€๊ฒฝํ•ด ๋ณด์ž.

function outerFunc() {
  var x = 10;
  var innerFunc = function () { console.log(x); };
  return innerFunc;
}

/**
 *  ํ•จ์ˆ˜ outerFunc๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ๋‚ด๋ถ€ ํ•จ์ˆ˜ innerFunc๊ฐ€ ๋ฐ˜ํ™˜๋œ๋‹ค.
 *  ๊ทธ๋ฆฌ๊ณ  ํ•จ์ˆ˜ outerFunc์˜ ์‹คํ–‰ ์ปจํ…์ŠคํŠธ๋Š” ์†Œ๋ฉธํ•œ๋‹ค.
 */
var inner = outerFunc();
inner(); // 10

ํ•จ์ˆ˜ outerFunc๋Š” ๋‚ด๋ถ€ํ•จ์ˆ˜ innerFunc๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ณ  ์ƒ์„ ๋งˆ๊ฐํ–ˆ๋‹ค.

์ฆ‰, ํ•จ์ˆ˜ outerFunc๋Š” ์‹คํ–‰๋œ ์ดํ›„ ์ฝœ์Šคํƒ(์‹คํ–‰ ์ปจํ…์ŠคํŠธ ์Šคํƒ)์—์„œ ์ œ๊ฑฐ๋˜์—ˆ์œผ๋ฏ€๋กœ ํ•จ์ˆ˜ outerFunc์˜ ๋ณ€์ˆ˜ x ๋˜ํ•œ ๋”์ด์ƒ ์œ ํšจํ•˜์ง€ ์•Š๊ฒŒ ๋˜์–ด ๋ณ€์ˆ˜ x์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์€ ๋‹ฌ๋ฆฌ ์—†์–ด ๋ณด์ธ๋‹ค.

 

๊ทธ๋Ÿฌ๋‚˜ ์œ„ ์ฝ”๋“œ์˜ ์‹คํ–‰ ๊ฒฐ๊ณผ๋Š” ๋ณ€์ˆ˜ x์˜ ๊ฐ’์ธ 10์ด๋‹ค.

์ด๋ฏธ life-cycle์ด ์ข…๋ฃŒ๋˜์–ด ์‹คํ–‰ ์ปจํ…์ŠคํŠธ ์Šคํƒ์—์„œ ์ œ๊ฑฐ๋œ ํ•จ์ˆ˜ outerFunc์˜ ์ง€์—ญ๋ณ€์ˆ˜ x๊ฐ€ ๋‹ค์‹œ ๋ถ€ํ™œ์ด๋ผ๋„ ํ•œ ๋“ฏ์ด ๋™์ž‘ํ•˜๊ณ  ์žˆ๋‹ค.

๋ˆˆ์—๋Š” ๋ณด์ด์ง€ ์•Š์ง€๋งŒ ๋ญ”๊ฐ€ ํŠน๋ณ„ํ•œ ์ผ์ด ์ผ์–ด๋‚˜๊ณ  ์žˆ๋Š” ๊ฒƒ์ด๋‹ค.

โ€‹

์ด์ฒ˜๋Ÿผ ์ž์‹ ์„ ํฌํ•จํ•˜๊ณ  ์žˆ๋Š” ์™ธ๋ถ€ํ•จ์ˆ˜๋ณด๋‹ค ๋‚ด๋ถ€ํ•จ์ˆ˜๊ฐ€ ๋” ์˜ค๋ž˜ ์œ ์ง€๋˜๋Š” ๊ฒฝ์šฐ, ์™ธ๋ถ€ ํ•จ์ˆ˜ ๋ฐ–์—์„œ ๋‚ด๋ถ€ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋˜๋”๋ผ๋„ ์™ธ๋ถ€ํ•จ์ˆ˜์˜ ์ง€์—ญ ๋ณ€์ˆ˜์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ ์ด๋Ÿฌํ•œ ํ•จ์ˆ˜๋ฅผ ํด๋กœ์ €(Closure)๋ผ๊ณ  ๋ถ€๋ฅด๋Š” ๊ฒƒ์ด๋‹ค.


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

โ€‹

์ƒํƒœ ์œ ์ง€

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

  1. closure ๋ผ๋Š” ์ด๋ฆ„์˜ ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค๊ณ  toggle ๋ณ€์ˆ˜์— ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•œ ๋ฆฌํ„ด๊ฐ’์ธ ๋‚ด๋ถ€ ํ•จ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
    ๋ฐ˜ํ™˜ํ•œ ํ•จ์ˆ˜๋Š” ์ž์‹ ์ด ์ƒ์„ฑ๋์„ ๋•Œ์˜ ๋ ‰์‹œ์ปฌ ํ™˜๊ฒฝ(Lexical environment)์— ์†ํ•œ ๋ณ€์ˆ˜ isShow๋ฅผ ๊ธฐ์–ตํ•˜๋Š” ํด๋กœ์ €๋‹ค. ํด๋กœ์ €๊ฐ€ ๊ธฐ์–ตํ•˜๋Š” ๋ณ€์ˆ˜ isShow๋Š” box ์š”์†Œ์˜ ํ‘œ์‹œ ์ƒํƒœ๋ฅผ ๋‚˜ํƒ€๋‚ธ๋‹ค.
  2. ํด๋กœ์ €๋ฅผ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋กœ์„œ ์ด๋ฒคํŠธ ํ”„๋กœํผํ‹ฐ์— ํ• ๋‹นํ–ˆ๋‹ค.
    ์ด๋ฒคํŠธ ํ”„๋กœํผํ‹ฐ์—์„œ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ์ธ ํด๋กœ์ €๋ฅผ ์ œ๊ฑฐํ•˜์ง€ ์•Š๋Š” ํ•œ ํด๋กœ์ €๊ฐ€ ๊ธฐ์–ตํ•˜๋Š” ๋ ‰์‹œ์ปฌ ํ™˜๊ฒฝ์˜ ๋ณ€์ˆ˜ isShow๋Š” ์†Œ๋ฉธํ•˜์ง€ ์•Š๋Š”๋‹ค.
    ๋‹ค์‹œ ๋งํ•ด ํ˜„์žฌ ์ƒํƒœ๋ฅผ ๊ธฐ์–ตํ•œ๋‹ค.
  3. ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด ์ด๋ฒคํŠธ ํ”„๋กœํผํ‹ฐ์— ํ• ๋‹นํ•œ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ์ธ ํด๋กœ์ €๊ฐ€ ํ˜ธ์ถœ๋œ๋‹ค.
    ์ด๋•Œ .box ์š”์†Œ์˜ ํ‘œ์‹œ ์ƒํƒœ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๋ณ€์ˆ˜ isShow์˜ ๊ฐ’์ด ๋ณ€๊ฒฝ๋œ๋‹ค.
    ๋ณ€์ˆ˜ isShow๋Š” ํด๋กœ์ €์— ์˜ํ•ด ์ฐธ์กฐ๋˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์œ ํšจํ•˜๋ฉฐ ์ž์‹ ์˜ ๋ณ€๊ฒฝ๋œ ์ตœ์‹  ์ƒํƒœ๋ฅผ ๊ฒŒ์†ํ•ด์„œ ์œ ์ง€ํ•œ๋‹ค.
<!DOCTYPE html>
<html>
<body>
  <button class="toggle">toggle</button>
  <div class="box" style="width: 100px; height: 100px; background: red;"></div>

  <script>
    var box = document.querySelector('.box');
    var toggleBtn = document.querySelector('.toggle');

    function closure() {
      var isShow = false;

      // โ‘  ํด๋กœ์ €๋ฅผ ๋ฐ˜ํ™˜
      return function () {
        box.style.display = isShow ? 'block' : 'none';
        // โ‘ข ์ƒํƒœ ๋ณ€๊ฒฝ
        isShow = !isShow;
      };
    }
    
    var toggle = closure(); // ํด๋กœ์ € ๋ฐ˜ํ™˜

    // โ‘ก ์ด๋ฒคํŠธ ํ”„๋กœํผํ‹ฐ์— ํด๋กœ์ €๋ฅผ ํ• ๋‹น
    toggleBtn.onclick = toggle;
  </script>
</body>
</html>

ํด๋กœ์ €-์ •๋ฆฌ

 

์ด์ฒ˜๋Ÿผ ํด๋กœ์ €๋Š” ํ˜„์žฌ ์ƒํƒœ(์œ„ ์˜ˆ์ œ์˜ ๊ฒฝ์šฐ .box ์š”์†Œ์˜ ํ‘œ์‹œ ์ƒํƒœ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” isShow ๋ณ€์ˆ˜)๋ฅผ ๊ธฐ์–ตํ•˜๊ณ  ์ด ์ƒํƒœ๊ฐ€ ๋ณ€๊ฒฝ๋˜์–ด๋„ ์ตœ์‹  ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•ด์•ผ ํ•˜๋Š” ์ƒํ™ฉ์— ๋งค์šฐ ์œ ์šฉํ•˜๋‹ค.

๋งŒ์•ฝ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์— ํด๋กœ์ €๋ผ๋Š” ๊ธฐ๋Šฅ์ด ์—†๋‹ค๋ฉด ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ์ „์—ญ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ๋ฐ–์— ์—†๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ์ „์—ญ ๋ณ€์ˆ˜๋Š” ์–ธ์ œ๋“ ์ง€ ๋ˆ„๊ตฌ๋‚˜ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๊ณ  ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋งŽ์€ ๋ถ€์ž‘์šฉ์„ ์œ ๋ฐœํ•ด ์˜ค๋ฅ˜์˜ ์›์ธ์ด ๋˜๋ฏ€๋กœ ์‚ฌ์šฉ์„ ์–ต์ œํ•ด์•ผ ํ•œ๋‹ค.

โ€‹

โ€‹

์ „์—ญ ๋ณ€์ˆ˜์˜ ์‚ฌ์šฉ ์–ต์ œ

๋ฒ„ํŠผ์ด ํด๋ฆญ๋  ๋•Œ๋งˆ๋‹ค ํด๋ฆญํ•œ ํšŸ์ˆ˜๊ฐ€ ๋ˆ„์ ๋˜์–ด ํ™”๋ฉด์— ํ‘œ์‹œ๋˜๋Š” ์นด์šดํ„ฐ๋ฅผ ๋งŒ๋“ค์–ด๋ณด์ž.

์ด ์˜ˆ์ œ์˜ ํด๋ฆญ๋œ ํšŸ์ˆ˜๊ฐ€ ๋ฐ”๋กœ ์œ ์ง€ํ•ด์•ผํ•  ์ƒํƒœ์ด๋‹ค.

// ์นด์šดํŠธ ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•œ ์ „์—ญ ๋ณ€์ˆ˜
var counter = 0;

function increase() {
  return ++counter;
}

Button.onclick = function () {
  count.innerHTML = increase();
};

์œ„ ์ฝ”๋“œ๋Š” ์ž˜ ๋™์ž‘ํ•˜์ง€๋งŒ ์˜ค๋ฅ˜๋ฅผ ๋ฐœ์ƒ์‹œํ‚ฌ ๊ฐ€๋Šฅ์„ฑ์„ ๋‚ดํฌํ•˜๊ณ  ์žˆ๋Š” ์ข‹์ง€ ์•Š์€ ์ฝ”๋“œ๋‹ค.

๋ณ€์ˆ˜ counter๋Š” ์ „์—ญ ๋ณ€์ˆ˜์ด๊ธฐ ๋•Œ๋ฌธ์— ์–ธ์ œ๋“ ์ง€ ๋ˆ„๊ตฌ๋‚˜ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๊ณ  ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋Š” ์˜๋„์น˜ ์•Š๊ฒŒ ๊ฐ’์ด ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค.

๋งŒ์•ฝ ๋ˆ„๊ตฐ๊ฐ€์— ์˜ํ•ด ์˜๋„์น˜ ์•Š๊ฒŒ ์ „์—ญ ๋ณ€์ˆ˜ counter์˜ ๊ฐ’์ด ๋ณ€๊ฒฝ๋๋‹ค๋ฉด ์ด๋Š” ์˜ค๋ฅ˜๋กœ ์ด์–ด์ง„๋‹ค.

๋”ฐ๋ผ์„œ ๋ณ€์ˆ˜ counter๋Š” ์นด์šดํ„ฐ๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” increase ํ•จ์ˆ˜๊ฐ€ ๊ด€๋ฆฌํ•˜๋Š” ๊ฒƒ์ด ๋ฐ”๋žŒ์งํ•˜๋‹ค.

 

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

function increase() {
  // ์นด์šดํŠธ ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•œ ์ง€์—ญ ๋ณ€์ˆ˜
  var counter = 0;
  return ++counter;
}

Button.onclick = function () {
  count.innerHTML = increase(); // ๋ฌด์กฐ๊ฑด 1์ด ๋ฐ˜ํ™˜ ๋œ๋‹ค
};

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

ํ•˜์ง€๋งŒ increase ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋  ๋•Œ๋งˆ๋‹ค ์ง€์—ญ๋ณ€์ˆ˜ counter๋ฅผ 0์œผ๋กœ ์ดˆ๊ธฐํ™”ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์–ธ์ œ๋‚˜ 1์ด ํ‘œ์‹œ๋œ๋‹ค.

๋‹ค์‹œ ๋งํ•ด ๋ณ€๊ฒฝ๋œ ์ด์ „ ์ƒํƒœ๋ฅผ ๊ธฐ์–ตํ•˜์ง€ ๋ชปํ•œ๋‹ค.

 

์ด์ „ ์ƒํƒœ๋ฅผ ๊ธฐ์–ตํ•˜๋„๋ก ํด๋กœ์ €๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•ด๋ณด์ž.

var increase = (function() { // (function() { ... })(); ์ฆ‰์‹œ์‹คํ–‰ํ•จ์ˆ˜
  var counter = 0;
      
  return function(){ // ํด๋กœ์ €
    return ++counter; 
  }
})();

Button.onclick = function () {
  count.innerHTML = increase(); // 1 .. 2 .. 3
};

์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์‹คํ–‰๋˜๋ฉด ์ฆ‰์‹œ์‹คํ–‰ํ•จ์ˆ˜(immediately-invoked function expression)๊ฐ€ ํ˜ธ์ถœ๋˜๊ณ ,

๋ณ€์ˆ˜ increase์—๋Š” ํ•จ์ˆ˜ function () { return ++counter; }๊ฐ€ ํ• ๋‹น๋œ๋‹ค.

 

โ€‹์ด ํ•จ์ˆ˜๋Š” ์ž์‹ ์ด ์ƒ์„ฑ๋์„ ๋•Œ์˜ ๋ ‰์‹œ์ปฌ ํ™˜๊ฒฝ(Lexical environment)์„ ๊ธฐ์–ตํ•˜๋Š” ํด๋กœ์ €๋‹ค.

์ฆ‰์‹œ์‹คํ–‰ํ•จ์ˆ˜๋Š” ํ˜ธ์ถœ๋œ ์ดํ›„ ์†Œ๋ฉธ๋˜์ง€๋งŒ ์ฆ‰์‹œ์‹คํ–‰ํ•จ์ˆ˜๊ฐ€ ๋ฐ˜ํ™˜ํ•œ ํ•จ์ˆ˜๋Š” ๋ณ€์ˆ˜ increase์— ํ• ๋‹น๋˜์–ด inclease ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด ํด๋ฆญ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ๋‚ด๋ถ€์—์„œ ํ˜ธ์ถœ๋œ๋‹ค.

โ€‹

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

๋”ฐ๋ผ์„œ ์ฆ‰์‹œ์‹คํ–‰ํ•จ์ˆ˜์˜ ๋ณ€์ˆ˜ counter์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๊ณ  ๋ณ€์ˆ˜ counter๋Š” ์ž์‹ ์„ ์ฐธ์กฐํ•˜๋Š” ํ•จ์ˆ˜๊ฐ€ ์†Œ๋ฉธ๋  ๋•Œ๊ฐ€์ง€ ์œ ์ง€๋œ๋‹ค.

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

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

ํด๋กœ์ ธ ์‹ค์ „ ์˜ˆ์ œ)

 

ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ ํด๋กœ์ €๋ฅผ ํ™œ์šฉ

function makeCounter(predicate) {
 
  var counter = 0; // ์นด์šดํŠธ ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•œ ์ž์œ  ๋ณ€์ˆ˜
  
  // ํด๋กœ์ €๋ฅผ ๋ฐ˜ํ™˜
  return function () {
    counter = predicate(counter);
    return counter;
  };
}

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

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


const increaser = makeCounter(increase);
/*
= function () {
    counter = function increase(counter) {
      return ++counter;
    }
    return counter;
  };
*/

console.log(increaser()); // 1
console.log(increaser()); // 2

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

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

ํ•จ์ˆ˜ makeCounter๊ฐ€ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜๋Š” ์ž์‹ ์ด ์ƒ์„ฑ๋์„ ๋•Œ์˜ ๋ ‰์‹œ์ปฌ ํ™˜๊ฒฝ์ธ ํ•จ์ˆ˜ makeCounter์˜ ์Šค์ฝ”ํ”„์— ์†ํ•œ ๋ณ€์ˆ˜ counter์„ ๊ธฐ์–ตํ•˜๋Š” ํด๋กœ์ €๋‹ค.

โ€‹

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

โ€‹

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


์ •๋ณด์˜ ์€๋‹‰

โ€‹์ƒ์„ฑ์ž ํ•จ์ˆ˜ Counter๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์ด๋ฅผ ํ†ตํ•ด counter ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค์–ด๋ณด์ž.

function Counter() {
  // ์นด์šดํŠธ๋ฅผ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•œ ์ž์œ  ๋ณ€์ˆ˜
  var counter = 0; // this.counter๋กœ ์•ˆํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— new ์ƒ์„ฑ์ž๋กœ ์ดˆ๊ธฐํ™”ํ•ด๋„ ์ด ๋ณ€์ˆ˜๋Š” ๊ฐ์ฒด์— ๋‹ด๊ธฐ์ง€ ์•Š๋Š”๋‹ค.
  
  // ํด๋กœ์ €
  this.increase = function () {
    return ++counter;
  };

  // ํด๋กœ์ €
  this.decrease = function () {
    return --counter;
  };
}

const counter = new Counter(); // counter๊ฐ์ฒด๋Š” increase decreaseํ•จ์ˆ˜ ๋‘๊ฐœ๋งŒ ๊ฐ–๊ฒŒ ๋œ๋‹ค.

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

์ƒ์„ฑ์ž ํ•จ์ˆ˜ Counter๋Š” increase, decrease ๋ฉ”์†Œ๋“œ๋ฅผ ๊ฐ–๋Š” ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.

์ด ๋ฉ”์†Œ๋“œ๋“ค์€ ๋ชจ๋‘ ์ž์‹ ์ด ์ƒ์„ฑ๋์„ ๋•Œ์˜ ๋ ‰์‹œ์ปฌ ํ™˜๊ฒฝ์ธ ์ƒ์„ฑ์ž ํ•จ์ˆ˜ Counter์˜ ์Šค์ฝ”ํ”„์— ์†ํ•œ ๋ณ€์ˆ˜ counter๋ฅผ ๊ธฐ์–ตํ•˜๋Š” ํด๋กœ์ €์ด๋ฉฐ ๋ ‰์‹œ์ปฌ ํ™˜๊ฒฝ์„ ๊ณต์œ ํ•œ๋‹ค.

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

โ€‹

์ด๋•Œ ์ƒ์„ฑ์ž ํ•จ์ˆ˜ Counter์˜ ๋ณ€์ˆ˜ counter๋Š” this์— ๋ฐ”์ธ๋”ฉ๋œ ํ”„๋กœํผํ‹ฐ๊ฐ€ ์•„๋‹ˆ๋ผ ๊ทธ๋ƒฅ ๋ณ€์ˆ˜๋‹ค.

counter๊ฐ€ this์— ๋ฐ”์ธ๋”ฉ๋œ ํ”„๋กœํผํ‹ฐ๋ผ๋ฉด ์ƒ์„ฑ์ž ํ•จ์ˆ˜ Counter๊ฐ€ ์ƒ์„ฑํ•œ ์ธ์Šคํ„ด์Šค๋ฅผ ํ†ตํ•ด ์™ธ๋ถ€์—์„œ ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•œ public ํ”„๋กœํผํ‹ฐ๊ฐ€ ๋˜์ง€๋งŒ

์ƒ์„ฑ์ž ํ•จ์ˆ˜ Counter ๋‚ด์—์„œ ์„ ์–ธ๋œ ๋ณ€์ˆ˜ counter๋Š” ์ƒ์„ฑ์ž ํ•จ์ˆ˜ Counter ์™ธ๋ถ€์—์„œ ์ ‘๊ทผํ•  ์ˆ˜ ์—†๋‹ค.

โ€‹

์ƒ์„ฑ์ž ํ•จ์ˆ˜ Counter๊ฐ€ ์ƒ์„ฑํ•œ ์ธ์Šคํ„ด์Šค์˜ ๋ฉ”์†Œ๋“œ์ธ increase, decrease๋Š” ํด๋กœ์ €์ด๊ธฐ ๋•Œ๋ฌธ์— ์ž์‹ ์ด ์ƒ์„ฑ๋์„ ๋•Œ์˜ ๋ ‰์‹œ์ปฌ ํ™˜๊ฒฝ์ธ ์ƒ์„ฑ์ž ํ•จ์ˆ˜ Counter์˜ ๋ณ€์ˆ˜ counter์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค.

โ€‹

์ด๋Ÿฌํ•œ ํด๋กœ์ €์˜ ํŠน์ง•์„ ์‚ฌ์šฉํ•ด ํด๋ž˜์Šค ๊ธฐ๋ฐ˜ ์–ธ์–ด์˜ private ํ‚ค์›Œ๋“œ๋ฅผ ํ‰๋‚ด๋‚ผ ์ˆ˜ ์žˆ๋‹ค.


์ž์ฃผ ๋ฐœ์ƒํ•˜๋Š” ํด๋กœ์ € ์‹ค์ˆ˜

var arr = [];

for (var i = 0; i < 5; i++) {
  arr[i] = function () { return i; };
}

for (var j = 0; j < arr.length; j++) {
  console.log(arr[j]()); // 5 5 5 5 5
}

๋ฐฐ์—ด arr์— 5๊ฐœ์˜ ํ•จ์ˆ˜๊ฐ€ ํ• ๋‹น๋˜๊ณ  ๊ฐ๊ฐ์˜ ํ•จ์ˆ˜๋Š” ์ˆœ์ฐจ์ ์œผ๋กœ 0, 1, 2, 3, 4๋ฅผ ๋ฐ˜ํ™˜ํ•  ๊ฒƒ์œผ๋กœ ๊ธฐ๋Œ€ํ•˜๊ฒ ์ง€๋งŒ ๊ฒฐ๊ณผ๋Š” ๊ทธ๋ ‡์ง€์•Š๋‹ค.

 

for ๋ฌธ์—์„œ ์‚ฌ์šฉํ•œ ๋ณ€์ˆ˜ i๋Š” ์ „์—ญ ๋ณ€์ˆ˜์ด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

var i= 110;

for (var i = 0; i < 5; i++) {
}

console.log(i) // 5

โ€‹

์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋ฅผ ํด๋กœ์ €๋ฅผ ์‚ฌ์šฉํ•ด ๋ฐ”๋ฅด๊ฒŒ ๋™์ž‘ํ•˜๋Š” ์ฝ”๋“œ๋กœ ๋งŒ๋“ค์–ด๋ณด์ž.

var arr = [];

for (var i = 0; i < 5; i++){
  arr[i] = (function (id) { // โ‘ก
    return function () {
      return id; // โ‘ข
    };
  }(i)); // โ‘ 
}

for (var j = 0; j < arr.length; j++) {
  console.log(arr[j]());
}
  1. ๋ฐฐ์—ด arr์—๋Š” ์ฆ‰์‹œ์‹คํ–‰ํ•จ์ˆ˜์— ์˜ํ•ด ํ•จ์ˆ˜๊ฐ€ ๋ฐ˜ํ™˜๋œ๋‹ค.
  2. ์ด๋•Œ ์ฆ‰์‹œ์‹คํ–‰ํ•จ์ˆ˜๋Š” i๋ฅผ ์ธ์ž๋กœ ์ „๋‹ฌ๋ฐ›๊ณ  ๋งค๊ฐœ๋ณ€์ˆ˜ id์— ํ• ๋‹นํ•œ ํ›„ ๋‚ด๋ถ€ ํ•จ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ณ  life-cycle์ด ์ข…๋ฃŒ๋œ๋‹ค. ๋งค๊ฐœ๋ณ€์ˆ˜ id๋Š” ์ž์œ ๋ณ€์ˆ˜๊ฐ€ ๋œ๋‹ค.
  3. ๋ฐฐ์—ด arr์— ํ• ๋‹น๋œ ํ•จ์ˆ˜๋Š” id๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค. ์ด๋•Œ id๋Š” ์ƒ์œ„ ์Šค์ฝ”ํ”„์˜ ์ž์œ ๋ณ€์ˆ˜์ด๋ฏ€๋กœ ๊ทธ ๊ฐ’์ด ์œ ์ง€๋œ๋‹ค.

โ€‹

์œ„ ์˜ˆ์ œ๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ํ•จ์ˆ˜ ๋ ˆ๋ฒจ ์Šค์ฝ”ํ”„ ํŠน์„ฑ์œผ๋กœ ์ธํ•ด for ๋ฃจํ”„์˜ ์ดˆ๊ธฐ๋ฌธ์—์„œ ์‚ฌ์šฉ๋œ ๋ณ€์ˆ˜์˜ ์Šค์ฝ”ํ”„๊ฐ€ ์ „์—ญ์ด ๋˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฐœ์ƒํ•˜๋Š” ํ˜„์ƒ์ด๋‹ค.

์‚ฌ์‹ค โ€‹ES6์˜ let ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ด์™€ ๊ฐ™์€ ๋ฌธ์ œ๋Š” ๋ง๋”ํžˆ ํ•ด๊ฒฐ๋œ๋‹ค.

const arr = [];

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

for (let i = 0; i < arr.length; i++) {
  console.log(arr[i]());
}

 

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

์ด ๋ฐฉ๋ฒ•์€ ๋ณ€์ˆ˜์™€ ๋ฐ˜๋ณต๋ฌธ์˜ ์‚ฌ์šฉ์„ ์–ต์ œํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์—ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์˜ค๋ฅ˜๋ฅผ ์ค„์ด๊ณ  ๊ฐ€๋…์„ฑ์„ ์ข‹๊ฒŒ ๋งŒ๋“ ๋‹ค.

const arr = new Array(5).fill(); // Array.prototype.fill() ์ธ์ž๋ฅผ ๋ฐฐ์—ด ์ธ์ˆ˜๋กœ
                                 // [undefined, undefined, undefined, undefined, undefined]
                                 // fill()์„ ์•ˆ๋ถ™์ผ๊ฒฝ์šฐ -> [empty x 5]
                                 
arr.forEach((v, i, array) => array[i] = () => i); // ๊ฐ ๋ฐฐ์—ด์›์†Œ์— ํด๋กœ์ € ํ•จ์ˆ˜(์™ธ๋ถ€ i ์ฐธ์กฐ)๋ฅผ ๋„ฃ๋Š”๋‹ค.

arr.forEach(f => console.log(f())); // 0 1 2 3 4
// ๊ฐ ๋ฐฐ์—ด์›์†Œ์— ์žˆ๋Š” ์ต๋ช…ํ•จ์ˆ˜๋“ค์ด ๊ฐ๊ฐ ์™ธ๋ถ€ ๋ณ€์ˆ˜ i๋ฅผ ๊ฐ๊ฐ ๋”ฐ๋กœ๋”ฐ๋กœ ๋…๋ฆฝ์ ์œผ๋กœ ์ฐธ์กฐํ•˜๊ณ  ์žˆ๋‹ค.

ํด๋กœ์ €๋Š” ํ•จ์ˆ˜์•ˆ์˜ ๋‚ด๋ถ€ํ•จ์ˆ˜๋กœ์„œ ์™ธ๋ถ€ํ•จ์ˆ˜์˜ ๋ณ€์ˆ˜๋ฅผ ์ฐธ์กฐ ํ•  ์ˆ˜์žˆ๋Š” ๋†ˆ์ด๋‹ค. 
๋”ฐ๋ผ์„œ ํด๋กœ์ €๋ฅผ ๋งŒ๋“ค๋ ค๋ฉด, ๋จผ์ € ์™ธ๋ถ€ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค๊ณ  ๋ณ€์ˆ˜๋ฅผ ์„ ์–ธํ•œ๋‹ค. 
๊ทธ๋ฆฌ๊ณ  ํด๋กœ์ € ํ•จ์ˆ˜๊ฐ€ ๊ทธ ๋ณ€์ˆ˜๋ฅผ ์ฐธ์กฐํ•˜๋„๋ก ํ•˜๋ฉด, ๋งˆ์น˜ static ์ •์ ๋ณ€์ˆ˜๋‚˜ private ๋ณ€์ˆ˜๋ฅผ ๋งŒ๋“ค์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค. โ€‹ 
์—ฌ๊ธฐ์„œ ํด๋กœ์ € ์ง€์—ญ ๋ณ€์ˆ˜๋Š” ํ•จ์ˆ˜๋‚ด์—์„œ ์„ ์–ธํ•ด๋„ ๋˜๊ณ , ์•„๊ทœ๋จผํŠธ๋กœ ์ง€์ •ํ•ด๋„ ๋œ๋‹ค.