javascript - 클로저

김동하·2020년 10월 6일
0

진짜 끝내주게 클로저 정리해놨는데 실수로 삭제했다. 다시 해야지.

클로저는 함수와 그 함수가 선언됐을 때의 렉시컬 환경과의 조합.

스코프는 함수를 호출할 때가 아니라 함수를 어디에 선언했는지에 따라 달라진다. 이를 렉시컬 스코핑이라고 한다.

function outer(){
  let x = 10;
  let inner = function (){
    console.log(x)
  }
  return inner
}

const innerFn = outer()
innerFn()

요것이 클로저. 클로저는 반환된 내부함수가 자신이 선언됐을 때 렉시컬 환경인 스코프를 기억하여 스코프 밖에서 호출되어도 스코프에 접근할 수 있는 함수. 즉, 클로저는 자신이 생성될 때의 렉시컬 환경을 기억하는 함수다.

전역 변수 사용 억제

 let counter = 0;

    function increase() {
      return ++counter;
    }

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

위 코드는 전역 변수를 지니고 있다. 변수 counter는 increse 함수가 관리하는 것이 옳다.

 function increase() {
      // 카운트 상태를 유지하기 위한 지역 변수
      let counter = 0;
      return ++counter;
    }

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

increase 함수가 호출될 때마다 지역 변수가 초기화되어 변경 이전 상태를 기억 못 한다. 클로저로 고치장

const increase = (function () {
      // 카운트 상태를 유지하기 위한 자유 변수
      let counter = 0;
      // 클로저를 반환
      return function () {
        return ++counter;
      };
    }());

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

즉시실행함수가 호출되고 변수 increase에 function () { return ++counter; }가 할당된다. 변수 counter는 외부에서 직접 접근할 수 없는 private 변수가 되었다.

정보 은닉

function Counter(){
  let cnt = 0;
  this.incre = function(){
    return ++cnt
  }
  this.decre = function(){
    return --cnt
  }
}
const counter = new Counter()

console.log(counter.incre()) // 1
console.log(counter.incre()) // 2
console.log(counter.decre()) // 1

생성자 함수가 생성한 객체의 메소드는 객체의 프로퍼티에만 접근할 수 있는 것이 아니라 자신이 기억하는 렉시컬 환경의 변수에도 접근할 수 있다. 이때 생성자 함수 Counter의 변수 cnt는 this에 바인딩된 프로퍼티가 아니라 변수다. cnt가 this에 바인딩된 프로퍼티면 인스턴스를 통해 접근이 가능하지만 생성자 함수 내 변수라 외부 접근 불가능이다. 하지만 생성자 함수 Counter의 인스턴스의 메소드들은 클로저라서 자신이 생설됐을 때의 렉시컬 환경인 생성자 함수의 변수에 접근 가능!

참고 : https://poiemaweb.com/js-closure
코어 자바스크립트

profile
프론트엔드 개발

0개의 댓글