자바스크립트 - Closure

코드위의승부사·2019년 12월 11일
0

JavaScript

목록 보기
4/8

Closure란?

먼저 MDN의 정의를 보면

Closures are functions that refer to independent(free) variables (variables that are used locally, but defined in anenclosing scope). In other words, these functions 'remember' the environment in which they were created.
클로저는 독립적인 변수를 가리키는 함수이다. 또는 클로저 안에 정의된 함수는 만들어진 환경을 기억한다.

Closure from MDN

function makeFunc() {
  var name = 'Mazilla';
  function displayName() {
    alert(name);
  }
  return displayName;
}

var myFunc = makeFunc();
// myFunc변수에 displayName을 리턴(displayName 함수 실행 전) 
// 유효범위의 어휘적 환경을 유지
myFunc();
// 리턴된 displayName 함수를 실행(name이 있는 어휘적 환경에 참조)
// 리턴하는 함수가 클로저를 형성

클로저는 함수와 함수가 선언된 어휘적 환경의 조합이다.
-> 여기서 환경은 클로저가 생성된 시점의 유효 범위 내에 있는 모든 지역변수로 구성된다.

function makeAdder(x) {
	var y = 1;
  	return function(z) {
      y = 100;
      return x + y + z;
    }
}

var add5 = makeAdder(5);
var add10 = makeAdder(10);
// 클로저에 x와 y의 환경이 저장됨 
// makeAdder 함수가 특정한 값을 인자로 가질 수 있는 함수들을 리턴

console.log(add5(2)); // 107(x:5 + y:100 + z:2)
console.log(add10(2)); // 112(x:10 + y:100 + z:2)
// 함수 실행 시 클로저에 저장된 x, y 값에 접근하여 값을 계산
// 같은 함수 본문 정의를 공유하지만 서로 다른 어휘적 환경을 저장
// 클로저가 리턴된 후에도 외부함수의 변수들에 접근 가능하다는 것을 보여주는 포인트이며 클로저에 단순히 값 형태로 전달되는 것이 아니라는 것을 의미한다.

클로저의 사용예시

클로저는 어떤 데이터(lexical scope)와 그 데이터를 조작하는 함수를 연관시켜주기 때문에 유용하다.
객체가 어떤 데이터와 하나 혹은 그 이상의 메소드들을 연관시킨다는 점에서 객체지향 프로그래밍과 같은 맥락이다.

function makeSizer(size) {
	return function() {
      document.body.style.fontSize = size + 'px';
    };
}

var size12 = makeSizer(12);
var size14 = makeSizer(14);
var size16 = makeSizer(16);

document.getElementById('size-12').onclick = size12;
document.getElementById('size-14').onclick = size14;
document.getElementById('size-16').onclick = size16;

모듈패턴(캡슐화:정보 은닉)

var counter = (function() {
	var privateCounter = 0;
  	function changeBy(val) {
      privateCounter += val;
    }
  return {
    increment: function() {
      changeB(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 함수의 private 아이템이 만들어 진다.
세가지 public 함수를 통해서만 접근되어야 한다.
counter를 생성하는 익명함수를 정의하고 그 함수를 즉시 호출하고 결과를 counter 변수에 할당 한다.
이 함수를 별도의 변수 makeCounter가 저장하고 이 변수를 이용해 여러개의 카운터를 만든다.

Closure from techsith

클로저에 대해 설명한 문장 중 가장 기억에 남는 문장이다.

Closures are nothing but FUNCTIONS WITH PRESERVED DATA
클로저란 그저 보존된 데이터를 갖고 있는 함수이다.

여기서 이 보존된 이라는 말이 한글로 번역했을때 약간 애매한데..
저장된걸 가져오는? 개념으로 보면 되겠다.

내부함수와 외부함수가 있을 경우에 내부함수에서 외부함수의 변수를 참조하는것을 Closure라고 알고 있었지만

아래와 같은 간단한경우도 Closure로 볼 수 있다.

var passed = 3;
var addTo = function() {
  var inner = 2;
  return passed + inner;
}

console.dir(addTo());
var passed = 4;
console.dir(addTo());

내부함수와 외부함수가 구분되어있는 일반적인 Closure

var addTo = function(passed){
  var add = function(inner){
    return passed + inner;
  };
  return add;
}

var addThree = new addTo(3);
var addFour = new addTo(4);

console.dir(addThree);
console.dir(addFour);

console을 통해서 클로져로 어떤 변수가 전달됬는지 확인이 가능하다.

Reference

profile
함께 성장하는 개발자가 되고 싶습니다.

0개의 댓글