Core JS 05. Closure

강지원·2022년 2월 3일
0

Core JS

목록 보기
5/5
post-thumbnail

Closure

어떤 함수 A에서 선언한 변수 a를 참조하는 내부함수 B를 외부로 전달할 경우 A의 실행 컨텍스트가 종료된 이후에도 변수 a가 사라지지 않는 현상.

var A = function () {
  var a = 1;
  var B = function () {
    return ++a;
  };
  return B;
};
var A2 = A();
console.log(A2()); //2
console.log(A2()); //3

만약 함수 B가 아닌 결과인 B()를 return했다면 B 변수의 값들은 언젠가 가비지 컬렉터에 의해 소멸했을 것이다. 꼭 return이 아니더라도, 지역변수를 참조하는 내부함수를 외부에 전달하면 클로저가 된다.

클로저의 메모리 관리

클로저는 어떤 필요에 의해 의도적으로 함수의 지역변수를
메모리를 소모하도록 함으로써 발생하게 되는데,
필요성이 사라진 시점에 더이상 메모리를 소모하지 않게 만들면 된다.
참조 카운트를 0으로 만들기 위해서는 식별자에 참조형이 아닌
기본형 데이터(보통 null/undefined)를 할당하면 된다.

var outer = function () {
  var a = 1;
  var inner = function () {
    return ++a;
  };
  return inner;
};

outer = null; // A 식별자의 B 함수 참조를 끊음.

클로저 활용 사례

콜백 함수 내부에서 외부 데이터 사용하고자 할 때

var fruits = ['apple', 'peach', 'orange']
var $ul = document.createElement('ul')

fruits.forEach(function (fruit) { //a
  var $li = document.createElement('li');
  $li.innerText = fruit;
  $li.addEventListener('click', function () {//b
    alert('your choice is ' + fruit);
  });
  $ul.appendChild($li);
});
document.body.appendChild($ul);

a : 클로저가 없다.
b : fruit이라는 외부변수를 참조하는 클로저가 있다.
b가 참조할 예정인 변수 fruit에 대해서는 a가 종료된 이후에도 가비지 컬렉터 대상에서 제외되기 때문에 계속 참조가 가능하다.

콜백 함수를 내부함수로 선언해서 외부변수를 직접 참조하는 방법으로 클로저를 사용했다.

고차함수를 통한 클로저 활용 예제

고차함수란?
함수를 인자로 받거나 함수를 리턴하는 함수

alertFruitBuilder의 실행결과로 반환된 함수에는 클로저가 존재한다.

var fruits = ['apple', 'peach', 'orange']
var $ul = document.createElement('ul')

var alertFruitBuilder = function (fruit) {
  return function () {
    alert('your choice is ' + fruit);
  };
};

fruits.forEach(function (fruit) {
  var $li = document.createElement('li');
  $li.innerText = fruit;
  $li.addEventListener('click', alertFruitBuilder(fruit));
  $ul.appendChild($li);
});

접근 권한 제어 (정보 은닉)

정보 은닉은 어떤 모듈 내부 로직에 의해 외부로의 노출을 최소화해 모듈간 결합도를 낮추고 유연성을 높이고자 하는 프로그래밍 언어의 중요한 개념 중 하나다. 흔히 접근 권한에는 public, private, protectd가 있다. 자바스크립트는 접근 권한을 직접 부여하도록 설계돼 있지 않지만, 클로저를 이용해 함수 차원에서 public/private 값 구분이 가능하다.

return을 활용해 일부의 변수에 대한 접근 권한을 부여한다.
1. 함수에서 지역변수 및 내부함수 등을 생성
2. 외부에 접근권한을 주고자 하는 대상들로 구성된 참조형 데이터를 return

var A = function () {
  var a = 1;
  var B = function () {
    return ++a;
  };
  return B; //내부함수 반환
};
var A2 = A();
console.log(A2());
console.log(A2());

return B;를 하면 A함수의 지역변수인 a의 값을 외부에 제공한다.

부분 적용 함수

부분 적용 함수란 n개의 인자를 받는 함수에 미리 m개의 인자만 넘겨 기억시켰다가, 나중에 (n-m)개의 인자를 넘기면 원래 함수의 실행 결과를 얻을 수 있게 하는 함수이다. this를 바인딩해야 하는 점을 제외하면 bind의 메서드의 실행결과가 바로 부분 적용 함수이다.

bind 활용 부분 적용 함수

var add = function () {
  var result = 0;
  for (var i = 0; i < arguments.lentgh; i++) {
    result += arguments[i];
  }
  return result;
};
var addPartial = add.bind(null, 1, 2, 3, 4, 5);
console.log(addPartial(6, 7, 8, 9, 10));
profile
'Why' better than 'Yes'

0개의 댓글