[JavaScript] Closure

Peter·2022년 3월 7일
0

JavaScript

목록 보기
4/9
post-thumbnail

Closure

포이에마웹
MDN Closure

클로져에 대한 개념을 알아야 한다고 했을 때 이름부터 어려워보여 위축됐던 기억이 있다. 하지만 살펴보면 너무 좋은 자바스크립트의 장점으로써 역할을 하고 있다는 것을 알 수 있다.

렉시컬 스코핑(Lexical scoping)

스코프는 함수를 어디에서 선언했는지로 결정된다.

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

outerFunc(); // 10
  • 렉시컬 스코핑에 의해 innerFunc이 outerFunc 스코프 안에 선언됐으므로 innerFunc은 x에 접근 가능하다.
function outerFunc() {
  var x = 10;
  var innerFunc = function () { console.log(x); };
  return innerFunc;
}

/**
 *  함수 outerFunc를 호출하면 내부 함수 innerFunc가 반환된다.
 *  그리고 함수 outerFunc의 실행 컨텍스트는 소멸한다.
 */
var inner = outerFunc();
inner(); // 10
  • outerFunc는 inner에 innerFunc를 반환하게 끝나게 된다
  • 따라서 outerFunc는 생을 마감하지만 반환한 innerFunc 스코프는 여전히 유효하다
  • innerFunc 함수가 선언됐을때 Lexical environment 또는 스코프를 기억하고 있다.
  • 이 개념이 '클로저'
  • x 와 같이 클로저에 의해 참조되는 변수를 자유변수라고 한다

클로저의 이점

상태 유지

function outerFunc() {
  var boolean = true
  var innerFunc = function () { 
    boolean = !boolean
    console.log(boolean); 
  };
  return innerFunc;
}

/**
 *  함수 outerFunc를 호출하면 내부 함수 innerFunc가 반환된다.
 *  그리고 함수 outerFunc의 실행 컨텍스트는 소멸한다.
 */
var inner = outerFunc();
inner(); // true
inner(); // false
inner(); // true
  • outerFunc는 innerFunc를 반환하고 사라지지만 boolean 자유변수는 남아 innerFunc가 접근한다
  • 불리언을 바꿔주는 로직에 따라 함수를 실행하면 그 변수 값이 저장되는 것을 알 수 있다.
  • 이 처럼 최근 반영한 값을 그대로 유지하고 있다

전역 변수 억제

var count = 0

function addCount() {
  return ++count;
}

addCount();
addCount();
addCount();
console.log(count); // 3
  • count라는 전역변수를 선언해놓고 함수로 제어하면 의도대로 작동은 하지만 다른 함수 또한 count에 접근 가능하기에 문제가 된다
function addCount() {
  var count = 0;
  return ++count;
}

addCount();
addCount();
addCount();
  • 혼돈을 주의해야 하는건 현재 addCount에 의해 숫자가 증가할 것이라 예상할 수 있지만
  • addcount가 호출될때마다 count 변수가 0으로 초기화되기 때문에 증가하는 값을 기억하지 못한다.
var addCount = (function() {
  var count = 0;
  return function() {
  	return ++count;
  };
}());

addCount();
addCount();
addCount();
  • 카운트를 증가시키는 함수를 반환하고 사라지는 함수를 addCount에 할당하면 카운트를 증가시키는 함수와 그 함수가 선언했던 렉시컬 환경에 있는 count 변수를 기억하게 된다.

정보 은닉

function Counter() {
  // 카운트를 유지하기 위한 자유 변수
  var counter = 0;

  // 클로저
  this.increase = function () {
    return ++counter;
  };

  // 클로저
  this.decrease = function () {
    return --counter;
  };
}

const counter = new Counter();

console.log(counter.increase()); // 1
console.log(counter.decrease()); // 0
  • 클래스의 private를 흉내내는 기능으로써 작용하게 된다.
profile
컴퓨터가 좋아

0개의 댓글