whatisthis?
javaScript. 클로저(Closure) 본문
___
>> Lexical scoping에 대해 포스팅 한 글을 먼저 참고하자.
___
클로저(Closure)
- 함수와 함수가 선언된 어휘적 환경의 조합
- 비공개 변수를 가질 수 있는 환경에 있는 함수
** 비공개 변수란?
클로저 함수 내부에 생성한 함수도 아니고, 매개변수도 아닌 변수.
var makeClosure = function() {
var name = 'zero';
return function () {
console.log(name);
}
};
var closure = makeClosure(); // function () { console.log(name); }
closure(); // 'zero';
위 예제에서 closure 함수 안에 console.log(name)이 있다. (makeClosure 함수의 코드가 그대로 존재)
name은 closure함수의 매개변수(parameter)도 아니고, closure 함수 내부에서 생성한 변수도 아니다.
-> name은 비공개변수이다.
function() { console.log(name) }은 name 변수나, name 변수가 있는 스코프에 대해 클로저라고 부를 수 있다.
>> 즉, 해당 함수에서 name을 생선한 것도 아니고 매개변수도 아니므로 (비공개변수를 가질 수 있는 환경)
** 컨텍스트 관점에서 살펴보자.
① 전역 컨텍스트 생성
"전역 컨텍스트": {
변수객체: {
arguments: null,
variable: [{ makeClosure: Function }, 'closure'], // maekeClosure은 함수표현식이므로
},
scopeChain: ['전역 변수객체'],
this: window,
}
② makeClosure() - makeClosure 컨텍스트 생성 (함수 호출시 생성되므로)
"makeClosure 컨텍스트": {
변수객체: {
arguments: null,
variable: [{ name: 'zero' }], // makeClosure 내에서 선언한 name변수
},
scopeChain: ['makeClosure 변수객체', '전역 변수객체'], // 본인 + 상위
this: window,
}
③ var closure = makeClosure(); 에 의해
function을 return하는데 (🔻아래 부분)
return function () {
console.log(name);
}
스코프체인은 makeClosure과 전역 변수객체를 포함한다.
위 예제 🔻
var makeClosure = function() {
var name = 'zero';
return function () {
console.log(name);
}
};
var closure = makeClosure(); // function () { console.log(name); }
closure(); // 'zero';
따라서 closure을 호출할 때 (마지막줄 closure(); 부분) closure 컨텍스트는
"closure 컨텍스트": {
변수객체: {
arguments: null,
variable: null,
scopeChain: ['closure 변수객체', 'makeClosure 변수객체', '전역 변수객체'],
this: window,
}
스코프체인을 보면 자기자신(closure) + function을 return할때의 스코프체인에 의해 makeClosure+전역도 포함
하게 된다.
💡 왜 클로저를 사용하는지?
비공개 변수를 만들어 활용 가능.
- 사용자가 조작할 걱정이 없고, 프로그램 사용자는 공개된 메소드만 사용해야 함.
- 즉, 사용자를 '통제'하기 위한 기본적인 방법이 클로저이다.
💡 클로저의 단점
- 성능 문제, 메모리 문제 발생 가능
- 비공개 변수는 언제 메모리관리를 해야할 지 모름 -> 메모리 낭비
- Scope Chain을 거슬러 올라가기 때문에 속도가 느림.
※ 추가 ※
EventListener을 for문으로 연결시 오류가 나는 이유
for (var i = 0; i < 5; i++) {
$('#target' + i).on('click', function() {
alert(i);
});
}
lexical Scoping에 의해 함수는 선언할 때 스코프가 생성된다.
즉, 이벤트리스너 안의 i는 외부의 i를 계속 참조하는 것.
i는 반복문 종료 후 최종적으로 5가 되기 때문에
결과는 계속 5가 나오게 됨.
>> 클로저를 만들어주면 해결됨
REFERENCE
https://www.zerocho.com/category/JavaScript/post/5741d96d094da4986bc950a0
이 포스팅은 zerocho님의 javascript 강의를 보고 작성한 글입니다.
공부+기록 용으로 작성한 것이며, 자세한 것은 위 포스팅을 참고하세요!
'WEB STUDY > JAVASCRIPT' 카테고리의 다른 글
javaScript. 이벤트 루프 (Event Loop) (0) | 2022.01.11 |
---|---|
javaScript. 호출 스택 (0) | 2022.01.11 |
javaScript. 호이스팅(Hoisting) (0) | 2022.01.11 |
javaScript. 함수선언식 vs. 함수표현식 (0) | 2022.01.11 |
javaScript. 실행 컨텍스트 (Execution Context) (0) | 2022.01.11 |