[JavaScript] 스코프(Scope)

미래·2023년 6월 8일
0

CS

목록 보기
4/6

스코프는 '범위'라는 의미다. 조금 더 자세히 말하자면, 자바스크립트에서 변수나 함수가 유효한 범위를 말하기 때문에 변수의 사용에 강한 영향력을 끼친다. 그리고 자바스크립트에서 중요한 개념인 컨텍스트로 연결되기 때문에 필수적으로 알아둬야 한다.

먼저, 전역변수와 지역변수를 보자.

자바스크립트에서는 주로 변수를 사용해 데이터를 저장하는데, 전역변수는 자바스크립트에서 제일 바깥 범위에 있는 변수, 즉 window 객체에 있는 변수다.

var x = 'global';
function ex() {
	var x = 'local';
    x = 'change';
}
ex(); //ex를 실행시켜 x의 값을 바꾼다.
alert(x); // 여전히 'global'이다.

여기서 ex 함수 안의 x는 ex 함수의 지역변수이고, 밖의 x는 전역변수다. 지역변수는 전역변수에 영향을 끼칠 수 없다. 바로 '스코프' 때문이다. var x = local은 ex의 함수 안에서만 데이터를 사용할 수 있다. x = change 또한 지역변수 x를 바꾸는 것이다.

그렇다면 다음과 같은 예를 보자.

var x = 'global'
function ex() {
	x = 'change';
}
ex();
alert(x); // 'change'를 되돌려준다.

위와 다른 점이 뭘까? 바로 ex 함수 안에서 var를 사용하지 않았다. x = change를 했을 때 전역변수가 바뀌는데, 이 이유는 뭘까? 자바스크립트는 변수의 범위를 호출한 함수의 지역 스코프부터 전역 변수들이 있는 전역 스코프까지 범위를 점차 넓혀가며 값을 찾기 때문이다. 함수의 ex 범위 안에 x가 없기 때문에 전역 스코프에서 x를 찾은 것.

이것이 바로 '스코프 체인Scope Chain'이다. 내부 함수에서는 외부의 함수에 접근이 가능하지만, 그 반대는 불가능하다. 그렇기에 모든 함수들은 전역 객체에 접근할 수 있다.

var name = 'mirae';
function outer() {
	console.log('외부', name); // mirae
    function inner() {
    	var cat = 'taeo';
        console.log('내부', name); // mirae
        }
    inner();
    };
outer();
console.log(cat); // undefined

inner와 outer 함수를 실행했을 때는 스코프 체인에 의해 name이 'mirae'라는 값을 가진다. 그렇지만 cat은 외부에서 내부의 값을 찾아야 하는 것이기 때문에 undefined가 뜬다.

그렇다면 스코프는 정확히 언제 생기는 걸까? 바로 함수의 사용이 아니라, 함수를 선언할 때 생긴다. 다음의 예제를 보자.

var name = 'mirae';
function log() {
	console.log(name);
}

function wrapper(){
	var name='taeo';
    log();
}

wrapper();

여기서 우리는 'taeo'가 출력될 거라고 생각하기가 쉬운데, 이 코드를 실행하면 'mirae'가 찍히는 걸 볼 수 있다. log 안의 name은 wrapper의 지역변수인 name이 아니라 전역변수 name을 가리키고 있기 때문이다. 이걸 바로 lexical scoping, 정적 범위라고 한다.

함수를 선언하는 순간 함수 내부의 변수는 자기 스코프로부터 가장 가까운 곳에서 변수를 참조하게 된다. 즉, log라는 함수는 mirae를 참조하게 된 것이다. 그래서 wrapper 안에서 taeo로 값을 바꿔줘도, 그대로 전역변수인 mirae를 참조하고 있기 때문에 mirae가 출력되는 것.

이 함수와 함수가 선언됐을 때의 렉시컬 환경이 바로 자바스크립트의 '클로저'라는 개념이다. 다음에 계속!

profile
여전히 에디터, 새롭게 개발자

0개의 댓글