ex 1.
function outer(){
var name = 'chanho'
return function(){
return name;
}
}
ex 2.
function outer() {
var count = 0;
return {
increment: function(){
count++
},
decrement: function(){
count--
},
getValue: function(){
return count
}
}
모질라에 따르면 '클로저는 함수와 함수가 선언된 어휘적 환경의 조합이다.' 라고 나와있다.
간단하게 정리하면 함수 밖에서 선언된 변수를 함수 내부에서 사용할 때 클로저가 생겨난다고 할 수 있다.
function outer(){
var name = 'yuddomack';
function inner(){
console.log(name);
}
return inner;
}
var innerFunc = outer();
innerFunc();
<외부 변수(name)를 함수 내부(inner)에서 사용>
위 코드에서 outer함수는 메모리 상에 아래와 같은 모습을 하게된다.
<메모리에서 outer 함수의 모습>
이제 var innerFunc = outer()를 통해서 inner 함수를 반환받게 되는데, 일반적으로 함수가 종료되면 메모리에서 소멸하기 때문에 아래와 같은 모습을 하게 된다..
<outer 함수가 종료되며 name에 대한 참조를 잃은 모습>
때문에 일반적으로, innerFunc를 호출해도 name에 대한 참조는 메모리에서 소멸하여 호출이 불가하게 된다.
하지만 클로저는 이러한(외부 변수와 같은) 환경 자체를 통째로 기억하는 공간을 형성한다.
<outer 영역은 소멸되었지만 클로저가 생성되어 여전히 참조 가능>
이러한 이유로 innrFunc는 여전히 자신의 외부에서 생성된 name 이라는 변수를 참조할 수 있게 된다.
scope : 코드작성 시 생김.(lexical scope)
let, const : 메모리공간은 생김, 이를 호이스팅이라고 하나 var과 같은 호이스팅의 효과는 아님.
execution context
어떤 함수가 호출되면, scope에 따라서 scope마다 메모리테이블이 생기고 이를 실행컨텍스트(execution context)라고 부른다.
실행컨텍스트는 실행시점이 중요함
4. 자유변수: 클로저에 의해 참조되는 외부함수의 변수
복습 1. testbuilder
실패사례
결과값 -> undefined
해결 방법
첫번째 : var을 let으로 바꿈 (182, 183번째 줄)
두번째 해당 부분을 IIFE(즉시실행함수)사용 (164, 191번째 줄)
복습 2.
function a(){
var b = 100;
function c(){
return b + 100;
}
c()
}
var d = a()
console.log(d)의 값은?
.
.
.
.
.
.
.
답: undefined
왜 undefined일까?
.
.
.
.
.
.
.
.
.
a함수는 c함수를 실행하였지만 반환하지 않음.
따라서 c() -> return c();로 변경
클로저가 가장 유용하게 사용되는 상황은 현재 상태를 기억하고 변경된 최신 상태를 유지하는 것
ex 1.
참조 : https://poiemaweb.com/js-closure
클로저 영역이 별도로 생성되는 모습은 마치 객체를 생성한 모습과 유사하다.
자바스크립트의 var는 전역적인 특성을 지니고 있지만 클로저의 특성을 이용하면 private 변수를 갖는 클래스 형태로 만들 수 있다.
student 함수의 반환값을 보면, 외부 변수(name, score 파라미터)가 함수의 내부(익명함수)에서 사용되는 모습을 보이기 때문에 클로저의 생성을 짐작할 수 있다.
프로토타입을 사용한 객체 생성도 가능하지만 이렇게 클로저를 이용하는 것으로도 클래스 객체의 모습을 흉내낼 수 있다.
<동일한 student 함수이지만 각각의 클로저가 독립적으로 생성되는 모습>
전역변수를 사용하게 되면 의도치 않게 변수의 수정이 발생할 수도 있으므로 이를 방지하기 위해 closuer사용
참조: https://poiemaweb.com/js-closure
자주 나오는 예제
privateCounter 접근시도 -> 역시 실패
그래서 변수에 counter를 할당한 후 변수를 본 결과 -> 오른쪽에 결과로 나오는 것들이 public // counter에는 있지만 안나오는 것들이 private
위의 결과로 깨닫게 된 것
그리고
참조
https://developer.mozilla.org/ko/docs/Web/JavaScript/Guide/Closures
https://poiemaweb.com/js-closure