Today I Learned

스코프, 전역변수

리꾸엘메 2022. 7. 14. 23:34

스코프

변수나 함수를 비롯한 식별자를 선언하고 값을 할당하는 것은 참조하기 위해서이다.

이 때 식별자를 참조할 수 있는 유효 범위는 선언된 위치에 따라 결정된다.

스코프는 식별자가 유효한 범위를 의미한다. 

하나의 식별자는 하나의 값을 가지기 때문에 같은 이름의 식별자는 존재할 수 없다.

하지만 스코프로 식별자의 유효 범위를 한정함으로써, 중복된 이름의 식별자를 사용할 수 있다.

 

전역스코프 / 지역스코프

const a = 1

function scope1() {
    const a = 10
    console.log(a) //10 지역스코프에서 선언한 a는 지역변수
}
scope1()
console.log(a) //1 a는 전역변수

전역스코프는 소스코드의 가장 바깥 영역이다.

전역스코프에서 선언한 식별자는 어디서든 참조할 수 있다. 

전역스코프에서 선언하는 변수를 전역변수라고 한다.

 

지역스코프는 함수 또는 블록 내부 영역이다.

지역스코프 내에서 선언된 변수는 지역변수라고 한다.

지역 변수의 유효 범위는 자신이 포함된 지역 스코프와 하위 지역스코프이다.

 

스코프 체인

const a = 1
function scope1() {
    const a = 10
    const b = 2
    console.log(a) //10 scope1 지역스코프의 지역변수 
    function scope2() {
        const a = 100
        console.log(a) //100 scope2 지역스코프의 지역변수
        console.log(b) //2 scope2에 변수b가 없기 떄문에 상위스코프에서 검색
    }
scope2()
}
scope1()
console.log(a) //1 a는 전역변수

함수는 전역스코프 뿐 아니라 함수 안에서도 정의할 수 있다.

지역스코프도 마찬가지로 전역스코프 내에 존재하지만, 지역스코프안에 또 지역스코프가 존재할 수 있다.

이렇게 중첩된 외부 스코프와 내부 스코프는 상위와 하위라는 계층적 구조를 가지는데 이를 스코프 체인이라고 한다.

중첩된 스코프안에서 식별자를 참조할 때, 자바스크립트는 하위에서 상위 스코프 순서로 변수를 검색한다.

그렇기 때문에 하위스코프에서 상위스코프의 식별자를 참조할 수 있지만, 반대 방향으로는 참조하지 못한다.

 

함수 레벨 스코프 / 블록 레벨 스코프

const a = 1
var b = 2

if (true) {
    const a = 10
    var b = 14
}
console.log(a) // 1 블록 레벨 스코프 (let, const)
console.log(b) // 14 함수 레벨 스코프 (var)

자바스크립트는 변수의 키워드에 따라 지역 스코프가 달라진다.

let, const로 선언된 변수는 모든 코드블록 내부 영역이 지역 스코프에 해당하지만,

var로 선언된 변수는 함수 내부 영역만 지역 스코프에 해당된다.

따라서 함수를 제외한 if, for, while, try/catch 등을 사용한 코드블록 내에서 var로 변수를 선언하는 경우 전역변수가 된다.

 

렉시컬 스코프

자바스크립트는 함수를 어디에서 정의했는지에 따라 상위 스코프가 결정되며, 호출된 위치는 고려되지 않는다.

이렇게 함수 정의가 실행될 때 스코프가 정적으로 결정되는 것을 렉시컬 스코프라고 한다.

반대로 함수가 호출된 위치에 따라 상위 스코프가 결정되는 것을 동적스코프(다이나믹 스코프)라고 한다. 

 

전역변수의 문제

지역변수의 생명 주기는 해당 스코프의 생명 주기와 일치한다.

상위 스코프에서는 하위 스코프의 변수를 참조할 수 없기 때문이다.

반면 전역변수의 경우 전역스코프에서 선언되며 소스코드가 끝날 때 까지 유지되기 때문에 몇 가지 문제를 가지고 있다.

- 암묵적 결합: 모든 스코프의 모든 코드에서 전역변수를 참조하고 값을 변경할 수 있어 예상치 못한 오류를 발생시킨다.

- 생명 주기가 길기 때문에, 메모리 공간을 오랫동안 차지한다.

- 스코프 체인의 최상단에 위치해 변수 검색에 오랜 시간이 걸린다. 

'Today I Learned' 카테고리의 다른 글

실행 컨텍스트  (0) 2022.07.21
var, let, const  (0) 2022.07.19
변수, 선언, 초기화, 할당 / 호이스팅  (0) 2022.07.12
타입스크립트 기본  (0) 2022.07.07
브랜치 전략, git flow  (0) 2022.07.06