closure 알아보기
Last updated
Was this helpful?
Last updated
Was this helpful?
클로저는 중요하다. 왜냐하면 클로저는 특정 함수 내의 스코프에 있는 것과 없는것을 제어하고 동일한 스코프 내에 있는 형제 함수 간에 변수를 공유하기 때문이다. 변수와 함수가 서로 연관되는 방식은 중요하니까 이해해야한다. 그래야 코드에서 무슨일이 일어나는지 알 수 있으니까..
클로저는 함수를 둘러싼 상태(lexical 환경)에 대한 참조로 번들된 함수의 결합이다. 다시말해서, 클로저는 내부 함수에서 외부 함수 스코프에 대한 접근을 가능하도록 한다. JS에서 클로저는 함수가 생성 될 떄마다 생성된다.
클로저를 사용하기 위해, 다른 함수 내부에서 함수를 정의하고 노출시켜라. 여기서 노출은 그 함수를 리턴하거나 다른 함수에 전달해야 한다.
내부 함수는 외부함수 스코프의 변수에 대한 접근이 가능하다. (외부함수가 리턴되고 나서도..)
클로저는 일반적으로 객체에 private 데이터를 제공하는데 사용된다. private 데이터는 구현이 아닌 interface로 프로그래밍하는데 도움이 되는 필수 속성이다. 이것은 좀 더 robust한 sw를 만들도록 도움을 주는 중요한 컨셉이다. 왜냐하면 interface 보다 구현체가 변경될 가능성이 더 높기 때문이다.
구현체가 아닌 인터페이스를 프로그래밍 해라
JS에서 클로저는 private 데이터를 가능하도록 해주는 주요 메커니즘이다. private data를 위해 클로저를 사용할 때, enclosed된 변수는 외부 함수 스코프에만 존재한다. 객체의 권한을 가진 메서드 를 거치는 방법을 제외하고 외부 스코프에서 데이터를 가져올 수 없다. JS에서 클로저 스코프에서 노출된 메서드는 특권을 가진다.
예를 들어보자,
.get
메서드는 getSecret()
스코프 내부에서 정의되었다. 이것은 getSecret()의 변수에 접근할 수 있고 특권을 가진 메서드로 만들어준다. 위 케이스의 경우에, 파라미터 secret
변수에 접근할 수 있다.
객체로만 private data를 만들 수 있는건 아니다. 클로저는 내부 상태에 영향을 받는 값을 리턴하는 stateful function 을 만들 때 사용된다.
함수형 프밍에서, 클로저는 partial application & currying에서 연속으로 사용된다. 이것은 몇몇 정의를 필요로한다.
Application: return value를 만들기 위해 인자 를 함수에 applying 하는 과정
Partial Application: 부분적으로 적용된 함수는 나중에 사용하기 위해 리턴된다. Partial application은 리턴된 함수 내부에서 1개 이상의 인자를 수정한다. 그리고 리턴된 함수는 function application을 완성하기 위해 남아있는 파라미터를 인자로 이용한다.
Partial application은 파라미터를 fix 하기 위해 클로저 스코프의 이점을 이용한다. 타겟 함수에 인자를 부분적응로 적용하는 generic 함수를 작성할 수 있다. 다음 시그니처를 갖는다.
여러개의 인자를 이용하는 함수를 가지고, 함수에 부분적으로 다음 인자를 적용할 수 있다. 그리고 남아있는 인자를 가지는 함수를 리턴한다.
숫자에 10을 더해주는 함수를 만들어보자. 우리는 add10()
이라고 부를거다. add10(5)
의 결과는 15다. partialApply()
함수를 이용하자
이 예제에서 10
은 fixed parameter 가 되고, add10()
클로저 스코프 내부에서 기억된다.
partialApply() 함수로 전달되는 인자인 rememberedArgs에 접근할 수 있는 함수를 간단히 리턴할 수 있다.
Q. 클로저란? A. 어떤 함수에서 반환된 내부함수가 자신이 선언된 환경(렉시컬 환경)인 스코프를 기억하여 그 외부함수의 환경에 접근 가능하다. 자신이 생성될 떄의 환경을 기억하는 함수다
Q. 클로저를 사용하려면? A. 어떤 함수 내부에서 외부 함수 스코프에 대한 접근 가능하도록 한다. 그래서 그 함수를 리턴하건나 다른 함수의 인자로 전달한다.
Q. 클로저를 어떻게 활용할 수 있나? A. private 데이터 제공. 이 데이터는 외부 함수 스코프에만 존재하므로 private 하게 접근 가능하다. 그래서 이 스코프에 접근 가능한 메서드를 생성하여 리턴하여 사용가능하다. 또한, stateful 함수를 만들 수 있다.(react의 hook이 상태를 클로저로 유지한다.) 이것은 currying을 이용하여 생성된다.
Q. 클로저를 EC를 이용하여 설명할 수 있는가? A. 리턴된 내부 함수 호출시 EC 생성된다. VO, scope chain, this 바인딩할 객체 결정된다. 스코프 체인은 자신이 선언된 EC의 스코프체인 위에 현재 VO를 추가한다. EC가 생성되고 코드 실행 한다. 코드 실행시 x를 스코프 체인을 통해 찾는다. 현재 VO에 x가 없기 때문에 다음 스코프체인에서 x를 찾아 10을 출력한다. 이미 콜스택(EC 스택)에서 제거되었는데 변수 x는 유효하지 않아 보인다. 하지만, 외부함수가 종료된 후에도 내부함수에서 외부함수의 지역변수에 접근가능하는데 이를 클로저라고 한다.