[JavaScript] closure(클로저)

DY·2022년 8월 21일
0

JavaScript

목록 보기
9/12

MDN 정의 : 함수와 함수가 선언된 어휘적(lexical) 환경의 조합을 말한다. 이때의 환경은 클로저가 생성된 시점의 유효 범위 내에 있는 모든 지역변수로 구성된다.

  • 클로저 함수란 외부 함수의 컨텍스트에 접근할 수 있는 내부 함수를 뜻한다. : 이 현상이 없으면 클로저라고 할수가 없다. 꼭 외부함수의 컨텍스트에 접근하는 무언가가 있어야 한다.

  • 데이터를 보존하는 함수다. : 외부 함수의 실행이 끝나더라도 외부 함수 내의 변수가 메모리에 저장이 된다. (메모리 해제 전까지 할당)

  • 현업에서는 코드가 방대하기 때문에 특정 기능에서 다른 부분을 참고 하기보다는 그자체에서 해결하기위해서 클로져를 쓴다.

  • Closure는 일급함수로서 전달할 수 있는 함수인데, 함수를 이리 저리 전달해서 사용할 때, 그 함수가 처음 정의될 때의 Context를 그대로 가지고 있을 필요가 있는 경우 사용한다.

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

	//x와 y의 환경이 저장됨					
    var add5 = makeAdder(5);
    var add10 = makeAdder(10);
    
    //클로저에 저장된 x,y값에 접근하여 계산
    console.log(add5(2)); // 107 (x:5 + y:100 + z:2)
    console.log(add10(2)); //112 (x:10 + y:100 + z:2)
  • 클로저는 makeAdder가 리턴하는 익명의 함수이다

  • makeAdder는 클로저를 사용하고 있다 라고 말할수 있음


var a = 0;
function foo() {
    var b = 0;
    return function() {
        console.log(++a, ++b);
    };
}

var f1 = foo();
var f2 = foo();

f1(); // 1,1
f1(); // 2,2 
f2(); // 3,1
f2(); // 4,2
  • foo는 한번만 실행되고 실행되었을 때 그때 상태의 변수 b자체를 저장한다. foo가 재실행 되는게 아니므로 재선언이 안된다.
  • 외부에서 직접적으로 value에 값을 할당할 수 없으므로 정보의 접근 제한이 가능하다. -> 캡슐화

var module = function() {
    
    //은닉될 멤버 정의
	let value = 0;
	function privateMethod(){
    	return value;
        }
    
    
    //공개될 멤버 정의
    return {
    	increase: () =>{
        	value = value +1;
        },
        decrease: function(){
        	value = value -1;
        },
        publicMethod: () => {
        	return privateMethod();
        }
    }
}

let testcase1 = module();
testcase1.increase();
console.log(testcase1.publicMethod());

let testcase2 = module();
testcase2.increase();
testcase2.increase();
testcase2.increase();
console.log(testcase2.publicMethod());
  • 클로저를 활용한 모듈 패턴이다.

  • 재활용이 가능한 module()함수를 이용하여 인스턴스를 여러개 만들 수 있고 객체의 메소드처럼 호출이 가능하다. public, private한정 자와 비슷하게 사용할 수 있다.

  • 클로저를 통해 데이터와 메서드를 같이 묶어서 다룰 수 있다.

  • 즉 클로저를 이용하여 객체를 리턴하는 함수를 작성한다면 서로에게 영향을 주지않는 객체들을 만들 수있다.


화살표 함수로 클로저 표현

const lamda1 = x => {
     return y => {
    	return x + y;
    }
}

const lamda2 = x = y => x - y;
}

lamda1(10)(20);
lamda2(10)(5);
 

메모리 해제

  • 클로저를 많이 쓰다보면 가비지 컬렉션에 의해 메모리가 해제되지 않는다. 곧 메모리 누수로 이어진다.

  • 쓰지않는 시점에서 null이나 undefined를 할당한다. // lamda2 = null;

정리

클로저는 함수와 함수가 선언된 어휘적 환경의 조합입니다.

어휘적 환경이란 함수가 선언된 주변 환경을 의미합니다. 주로 외부 함수(outer function)의 변수가 내부 함수(inner function)의 어휘적 환경에 포함됩니다. 그래서 내부 함수가 리턴되어도 나중에 클로저의 어휘적 환경에 접근하여 외부 함수의 변수에 접근할 수 있습니다.

클로저는 Javascript어떤 함수에서든 가지고 있습니다. 어떤 함수는 전역 변수에 접근할 수 있기 때문입니다.

자바스크립트에서 private 메서드를 구현하기 위해서도 클로저를 활용할 수 있습니다. 클로저 내에 있는 변수는 외부에서 접근할 수 없기 때문에, 클로져 내에 있는 변수를 활용 할 수 있는 private 메서드만 따로 노출시켜서 인터페이스처럼 사용할 수 있게 됩니다.

profile
프론트엔드 개발자가 되기 위해 공부중입니다. 블로그는 공부한 내용을 올리고 있습니다.

0개의 댓글