클로저 - 정리중

김명성·2022년 1월 29일
0

자바스크립트

목록 보기
8/26

내부변수를 사용하는 외부함수를 다른 지역의 변수에 할당함으로써
내부 변수에 접근할 수 있게 한다. - 클로저

var counter = (function() {
var privateCounter = 0;
function changeBy(val) {
privateCounter += val;
}
return {
increment: function() {
changeBy(1);
},
decrement: function() {
changeBy(-1);
},
value: function() {
return privateCounter;
}
};
})();
console.log(counter.value()); // logs 0
counter.increment();
counter.increment();
console.log(counter.value()); // logs 2
counter.decrement();
console.log(counter.value()); // logs 1
이전 예제에서 각 클로저들이 고유한 문법적 환경을 가졌지만
여기서 우리는 counter.increment, counter.decrement, counter.value
세 함수에 의해 공유되는 하나의 어휘적 환경을 만든다.
공유되는 어휘적 환경은 실행되는 익명 함수 안에서 만들어진다.
이 익명 함수는 정의되는 즉시 실행된다.
이 어휘적 환경은 두 개의 프라이빗 아이템을 포함한다.
하나는 privateCounter라는 변수이고 나머지 하나는 changeBy라는 함수이다.
둘 다 익명 함수 외부에서 접근될 수 없다.
대신에 익명 래퍼에서 반환된 세 개의 퍼블릭 함수를 통해서만 접근되어야만 한다.

위의 세 가지 퍼블릭 함수는 같은 환경을 공유하는 클로저다.
자바스크립트의 어휘적 유효 범위 덕분에 세 함수 각각 privateCounter 변수와
changeBy 함수에 접근할 수 있다.

카운터를 생성하는 익명 함수를 정의하고 그 함수를 즉시 호출하고
결과를 counter 변수에 할당하는 것을 알아차렸을 것이다.
이 함수를 별도의 변수 makeCounter 저장하고
이 변수를 이용해 여러 개의 카운터를 만들 수 있다.

  1. 카운터를 생성하는 익명 함수를 정의하고 그 함수를 즉시 호출하고
    결과를 counter 변수에 할당하는 것을 알아차렸을 것이다.
    이 함수를 별도의 변수 makeCounter 저장하고
    이 변수를 이용해 여러 개의 카운터를 만들 수 있다.

    var makeCounter = function() {
      var privateCounter = 0;
      function changeBy(val) {
        privateCounter += val;
      }
      return {
        increment: function() {
          changeBy(1);
        },
        decrement: function() {
          changeBy(-1);
        },
        value: function() {
          return privateCounter;
        }
      }
    };
    
    var counter1 = makeCounter();
    var counter2 = makeCounter();
    alert(counter1.value()); /* 0 */
    counter1.increment();
    counter1.increment();
    alert(counter1.value()); /* 2 */
    counter1.decrement();
    alert(counter1.value()); /* 1 */
    alert(counter2.value()); /* 0 */

두 개의 카운터가 어떻게 다른 카운터와 독립성을 유지하는지 주목해보자.
각 클로저는 그들 고유의 클로저를 통한 privateCounter 변수의 다른 버전을 참조한다.
각 카운터가 호출될 때마다; 하나의 클로저에서 변수 값을 변경해도
다른 클로저의 값에는 영향을 주지 않는다.

// 전역 범위 (global scope)
var e = 10;
function sum(a){
  return function(b){
    return function(c){
      // 외부 함수 범위 (outer functions scope)
      return function(d){
        // 지역 범위 (local scope)
        return a + b + c + d + e;
      }
    }
  }
}

console.log(sum(1)(2)(3)(4)); // log 20 // 


// 전역 범위 (global scope)
var e = 10;
function sum(a){
  return function(b){
    return function(c){
      // 외부 함수 범위 (outer functions scope)
      return function(d){
        // 지역 범위 (local scope)
        return a + b + c + d + e;
      }
    }
  }
}

console.log(sum(1)(2)(3)(4)); // log 20

// 익명 함수 없이 작성할 수도 있다.

// 전역 범위 (global scope)
var e = 10;
function sum(a){
  return function sum2(b){
    return function sum3(c){
      // 외부 함수 범위 (outer functions scope)
      return function sum4(d){
        // 지역 범위 (local scope)
        return a + b + c + d + e;
      }
    }
  }
}

var s = sum(1);
var s1 = s(2);
var s2 = s1(3);
var s3 = s2(4);
console.log(s3) //log 20

0개의 댓글