이 포스팅에서는 내부, 외부함수를 알아보고 클로저, 클로저와 연관된 랙시컬 스코프에 대한 간단히 알아본다.
1. 클로저와 내부, 외부 함수
- 클로저는 중첩 함수에서 외부 함수가 종료되어도 내부 함수에서 외부 함수에 접근할 수 있는 환경을 말한다.
- 내부 함수는 함수 안에 선언된 함수를 뜻하며, 외부 함수는 내부 함수를 포함하고 있는 함수를 말한다.
- 아래 예시에서
outer()
는 외부함수,inner()
는 내부함수이다.
function outer(){ // 내부 함수를 포함하고 있는 외부 함수
const inner = function() { // 특정 함수 내부에 선언된 내부 함수
console.log('hello')
}
inner();
}
outer(); // hello
outer()
는 중첩 함수 형태이며,inner()
(내부함수)는outer()
(외부함수)에서 선언되어 있다.
그런데, 내부함수를 생성하는 이유는 무엇일까?
- 그 이유는 특정 함수에서 사용할 함수를 정의할 때, 내부함수로 선언하면 응집성 측면에서 좋기 때문이다.
- 아래 예시를 보면,
inner()
는outer()
바깥에서는 호출될 수 없다. (prviate로 사용 가능) - 그렇기 때문에
inner()
의 사용 범위를 제한할 수 있다. (응집성 보장)
function outer(){
const inner = function() {
console.log('hello')
}
inner();
}
inner(); // inner is not defined
2. 클로저는 무엇일까
- 앞서 언급했듯이 클로저는 외부 함수가 종료되도 내부 함수에서 외부 함수에 접근할 수 있는 환경을 말한다.
내부함수가 외부함수에 접근할 수 있다? 이 말은 무엇을 뜻하는 걸까?
- 이 말은 내부 함수가 외부 함수의 지역 변수에 접근할 수 있음을 뜻한다.
- 예시를 살펴보자!
(1) 클로저 예시 1
- 이번에도
outer()
,inner()
함수를 가져와보았다. - 외부함수인
outer()
에서는title
변수와inner()
가 선언되어 있다.
function outer(){
var title = 'coding everybody'; // 외부 함수에 정의된 지역 변수
function inner(){} // 외부 함수에 선언된 내부 함수
inner();
}
- 클로저가 가능하다면,
inner()
에서outer()
의 지역변수에 접근할 수 있을 것이다.
function outer(){
var title = 'coding everybody'; //외부함수에 정의된 지역변수
function inner(){
console.log(title); // 내부함수에서는 외부함수의 지역변수에 접근할 수 있음
}
inner();
}
outer()
를 호출해보면,inner()
의console.log(title)
이 실행되고,inner()
에title
이 없기 때문에,inner()
의 외부함수(outer()
)의title
을 사용하게 된다.
outer(); // coding everybody
(2) 클로저 예시 2
- 그렇다면, 외부 함수에서 내부 함수를
return
하는 경우에는 어떻게 될까? outer()
에서는 arrow function을 리턴하고 있다.- 리턴을 하면 해당 함수의 로직은 종료되며, 내부에 선언된 변수가 소멸되는 게 자연스럽다.
function outer(){
var title = 'coding everybody';
return () => (console.log(title)) // arrow function
}
- 하지만 실제로
outer()
를 실행해보면title
변수가 출력된다.
const inner = outer();
inner(); // coding everybody
리턴을 하면 해당 함수가 종료되고 함수 내부에 선언된 값들이 소멸될텐데 왜 값에 접근할 수 있을까?
- 그 이유는 내부 함수에서 외부 함수의 지역 변수를 사용하는 경우, 외부 함수의 변수를 소멸시키지 않기 때문이다.
3. 왜 접근할 수 있을까?
- 우리는 예시를 통해, 내부함수에서 외부함수의 지역변수에 접근(클로저)할 수 있음을 알게 되었다.
그런데 외부 함수의 지역변수에 접근할 수 있는 이유가 무엇일까? 왜 클로저가 가능한걸까?
js
에서는 스코프라는 말이 존재한다.- 스코프란, 변수에 접근가능한 범위를 얘기한다.
- 크게 지역 스코프, 전역 스코프가 있는데, 클로저에는 그 중 랙시컬 스코프 개념이 중요하다.
랙시컬 스코프는 무엇인가요?
- 랙시컬 스코프는 함수를 어디(where)에 선언하느냐에 따라 함수 접근 범위가 결정되는 걸 말한다.
- 함수는 이 랙시컬 스코프로 인해 자신의 상위 함수에 접근할 수 있다.
- 만약
A()
내부에B()
를 선언했다면, 랙시컬 스코프에 의해B()
는 (B()의 상위인)A()
에 접근할 수 있다.
function A() {
const a = 12;
function B() {
console.log(a); // A()의 a변수에 접근 가능
}
}
- 결국 랙시컬 스코프로 인해, 클로저가 가능해지는 것이다.
추가적으로 랙시컬 스코프에 대한 알고 싶다면 이 링크를 확인해보자 🙂
반응형
'개발 기술 > 개발 이야기' 카테고리의 다른 글
[JS] 호이스팅(hoisting) (0) | 2021.12.21 |
---|---|
디자인 패턴1, 옵저버란? (0) | 2021.12.08 |
call, apply, bind의 차이 (0) | 2021.11.25 |
랙시컬 스코프(정적 스코프)는 무엇일까? (0) | 2021.11.22 |
promise와 async await의 차이점 (0) | 2021.11.17 |
댓글