들어가기에 앞서,
MDN에서 클로저의 정의를 보자 .
" 클로저 함수는 함수와 그 함수가 선언된 렉시컬 환경과의 조합이다. "
클로저를 알기 전 '렉시컬 스코프' 에 대해 알아보자.
🚀 렉시컬 스코프 (정적 스코프)
- 자바스크립트 엔진은 함수를 어디서 호출했는지가 아니라 함수를 어디에 정의했는지에 따라 상위 스코프를 결정한다.
- 함수가 호출된 위치는 상위 스코프 결정에 어떤 영향도 주지 않는다.
- 함수의 상위 스코프는 언제나 자신이 정의된 스코프다.
( 함수가 호출될 때마다 함수의 상위 스코프를 참조할 필요가 있기 때문)
🚀 클로저
- 폐쇄된 공간 안에 데이터에 접근하기 위한 테크닉
- 내부함수의 외부 함수 접근(권한) 테크닉
- 변수 은닉과 메모리 효율, 코드효율을 극대화 하기위해 사용
const x =1 ;
function outerFunc(){
const x =100
innerFunc();
}
function innerFunc (){
console.log(x);
}
outerFunc();
innerFunc을 outer밖에 정의하였고 , outerFunc안에서 호출한 상태이다 .
이경우 innerFunc이 호출된 outerFunc스코프 상의 x값 100을 출력할것이다라고 예상할수도 있지지만
innerFunC은 x=100에 접근하지 못한다. 정의된 곳을 기준으로 상위 스코프에 접근하여 x=1의 값을 출력한다.
[결과]
🚀 [예제1]
function makeAdder(x) {
var y = 1;
return function(z) {
y = 100;
return x + y + z;
};
}
var add5 = makeAdder(5);
var add10 = makeAdder(10);
console.log(add5(2));
console.log(add10(2));
함수 실행시 클로저 값에 저장된 x, y 값에 접근하여 값을 계산한다.
여기서 클로저는 add5 , add10이 된다.
add5와 add10은 functuon이고 , 그 안에 변수값을 보면
add5에는 x=5 , y=100가 있을것이고 , add10에는 x=10,y=100으로 있을것이다.
add함수 자체에 x값이 정의되어있지 않지만 add함수가 정의된 곳을 기준으로 렉시컬 스코프를 접근 할 수 있기 때문에 x값에 접근 할 수 있었던 것이다.
🚀 [예제2]
// 1
const x = 100;
function a() {
const x = 1;
b();
}
function b() {
console.log(x);
}
a(); // 100
b(); // 100
a()와 b()는 같은 스코프 상에서 정의되어있고, b()를 a() 안의 중첩함수로 호출하였다.
하지만 a()안에서 호출되었다고 해서 x=1을 접근할수 없다.
그렇다면 렉시컬 스코프 기준 상위 스코프는 x=100으로 정의되어 있으므로 a() b() 모두 100이 호출된다.
// 2
const xx = 100;
function a() {
const xx = 1;
function b() {
console.log(xx);
}
b();
}
a();
a()안에 b()가 정의되었고, 호출되었다. 이 경우 렉시컬 스코프 기준 상위스코프는 a()가 되므로
xx=1에 접근 가능하다. a()가 호출되고 b()가 호출되었을때 xx값은 1이 된다.
(참고로 b()는 a()안에 선언되었으므로 a()와 같은 스코프 상에서 b()를 호출 할 수 없다. )
🚀 [예제3]
function 승수제조기(){
let value = 0;
function 승수(){
return ++value**2
}
return 승수
}
let 승 = 승수제조기();
승()
승()
승()
value //출력할 수 없습니다. 은닉화가 되었기 때문입니다.
함수를 호출할때 value값이 1씩 증가되면서 value값이 저장되어 호출된다.
[결과]
끝으로
- 이런 클로저를 이용하여 private method를 흉내낼 수 도 있다. 이것을 모듈패턴이라 한다.
- 클로저가 필요하지 않는 데 다른 함수 내에서 불필요하게 작성하는것은 처리속도와 메모리 소비 측면에서 부정적인 영향을 미친다.
생활코딩님 클로저 정의 |
"부모 함수 안에서 자식 함수를 선언하면 자식함수를 어디에서 호출하더라도 자식함수 안에서 부모함수의 변수에 접근할 수 있습니다. " |
'FE > JavaScript' 카테고리의 다른 글
[JS] DOM - Event Flow (0) | 2022.05.12 |
---|---|
[JS] this (0) | 2022.05.11 |
[JS] 구조분해 할당 (0) | 2022.05.11 |
[JS] for of 과 for in (0) | 2022.05.11 |
[JS] 배열의 메소드 - find , filter ,map (0) | 2022.05.11 |