본문 바로가기
카테고리 없음

스코프(Scope), 클로저(Closure)

by 찬찬2 2022. 10. 10.

■ 스코프(scope)

- Scope란 사전적인 의미로 범위이다. 그렇다면 어떤 범위를 말할까? 식별자(변수, 함수, 클래스 등)가 참조될 범위를 말한다. 변수 이름, 함수 이름, 클래스 이름과 같은 식별자가 본인이 선언된 위치에 따라 다른 코드에서 "자신이 참조될 수 있을지 없을지 결정"되는 것을 말한다.

 

스코프 체인(지역 스코프, 전역 스코프)

 

- 자바스크립트 엔진은 변수를 참조할때 스코프 체인을 바탕으로 참조한다. (참조는 아래에서 부터 위로)

 

스코프 레벨 종류

1. 블록 레벨 스코프: "{ }" 중괄호를 하나의 블록이라고 볼 수 있다. (if, for, switch, try/actch, while etc...)

** let/const는 블록 레벨 스코프를 따른다.

2. 함수 레벨 스코프: 함수 내에서 선언된 변수는 함수 내에서만 유효하며 함수 외부에서는 참조할 수 없다. 즉, 함수 내부에서 선언한 변수는 지역 변수이며 함수 외부에서 선언한 변수는 모두 전역 변수이다

 

[중요] var는 함수 레벨 스코프만 지역 스코프로 인정한다.

 

/* var는 블록 레벨 스코프를 지역변수로 인정하지 않는다. */
var a = 123;

if(true){
	var a = 456;
	var b = 456;
}

console.log(a); // 456
console.log(b); // 456

/* var는 함수 레벨 스코프만 지역변수로 인정한다. */
var a = 123;

function myFunc(){
	var a = 456;
	var b = 456;
}

console.log(a); // 123
console.log(b); // ReferebceError: b is not defined

 

함수가 어디서 정의되었는지에 따라 스코프의 종류가 나뉜다.

1. 동적 스코프: 함수가 호출되는 시점에 식별자를 결정

2. 정적 스코프(렉시컬 스코프): 함수가 정의되는 시점식별자를 결정. (또는 선언된 위치에 따라)

** 자바스크립트는 정적 스코프를 사용한다

 

실행컨텍스트란?

 

 클로저(closure)

- 함수의 중첩관계에서 찾아볼 수 있다.

- 중첩관계에서 상위 함수의 생명주기가 끝나도 중첩 함수는 상위 함수의 렉시컬 환경을 기억한다. 

- 클로저는 함수와 그 함수가 선언됐을 때의 렉시컬 환경(Lexical environment)과의 조합이다. (MDN 참조)

 

var name = `Warning`;
function outer() {
    var name = `closure`;
        return function inner() {
        console.log(name);
    };
}

var callFunc = outer();
callFunc(); // closure

 

"그 함수가 선언됐을 때의 렉시컬 환경"은 함수가 정의된 위치의 스코프, 즉 상위 스코프를 의미하는 실행 컨텍스트의 렉시컬 환경을 말한다. 자바스크립트의 모든 함수는 자신의 상위 스코프를 기억한다. 모든 함수가 기억하는 상위 스코프는 함수를 어디서 호출하든 산관없이 유지된다.

그렇기 때문에 자신이 기억하는 상위 스코프의 식별자를 참조할 수 있으며 식별자에 바인딩된 값을 변경할 수도 있다.

 

중첩함수는 이미 생명주기가 종료한 외부함수의 변수를 참조할 수 있다. 이러한 중첩 함수를 클로저라고 부른다.

 

렉시컬 환경

 

 

 

클로저의 대표적인 샘플. (중첩된 함수, 익명함수가 클로저이다.)

 

참고링크#2

참고링크#1

댓글