[JS] (13) 스코프

sehannnnnnn·2021년 7월 28일
0

JavaScript DeepDive

목록 보기
6/7
post-thumbnail

스코프란?

스코프는 함수, 변수, 객체 등등을 사용할 수 있는 유효범위를 말한다.

ex)

  • var, let, const로 선언한 변수들의 스코프는 각각 다르게 작용한다.
  • 함수의 매개변수는 함수 몸체 내부에서만 참조할 수 있다.
var var1 = 1; //코드 블럭 외부에서 선언

if (true) {
	var var2 = 2; //코드 블럭 내부에서 선언
    	if (true) {
        var var3 = 3;  //중첩된 코드블록 내에서 선언
        }
}

function foo () {
	var var4 = 4; //함수 내에서 선언
    	function bar () {
        	var var5 = 5; //중첩함수 내에서 선언
        }
}
console.log(var1); //1
console.log(var2); //2
console.log(var3); //3
console.log(var4); //Reference Error
console.log(var5); //Reference Error

모든 식별자는 자신이 선언된 위치에 의해 다른 코드 식별자가 자신을 참조할 수 있는 유효범위가 결정된다. 이를 스코프라 한다. 스코프는 식별자가 유요한 범위를 말한다.

또한 스코프는 서로 같은 이름의 식별자를 구분하는 기준이 되기도 한다.

var x = 'global';

function foo() {
	var x = 'local';
    	console.log(x); //local
}

console.log(x); //global

위 코드처럼 두개의 다른 위치에서 x라는 식별자의 변수가 선언된 경우, 자바스크립트는 해당 변수들의 스코프로 두 변수를 비교하고 알맞은 변수를 참조한다. (마치 서울 사는 김민수, 부산 사는 김민수)

스코프라는 개념이 없다면 같은 이름을 갖는 변수는 충돌을 일으키고 프로그램 전체에서 하나밖에 사용할 수 없다.


스코프의 종류

구분설명스코프변수
전역코드의 가장 바깥 영역전역 스코프전역변수
지역함수 몸체 내부지역 스코프지역변수

전역변수는 코드 가장 바깥 영역에서 선언되었으며 어디서든 참조 할 수 있다.
지역변수는 자신의 지역(함수 몸체내부) 스코프와 하위 지역 스코프에서 유효하다.

자바스크립트 엔진은 스코프 체인을 통해 참조할 변수를 검색한다.

스코프 체인

함수는 중첩될 수 있으므로 함수의 지역스코프도 중첩 될 수 있다. 스코프 또한 함수와 마찬가지로 계층적인 구조를 갖게 되는데 이렇게 연결된 것을 스코프 체인 이라고 한다.

(최상위 스코프) 전역스코프 ->
outer 함수의 지역스코프 ->
inner 함수의 지역스코프

자바스크립트 엔진은 변수를 참조할 때 스코프 체인을 통해 해당 변수를 참조하는 코드에서 시작하여 상위 스코프 방향으로 이동하며 선언된 변수를 검색한다.
스코프체인은 물리적인 실체로 존재함! 렉시컬 환경(자료구조)를 실제로 생성함

해당 변수를 호출(참조) 하면 일단 자기가 선언된 지역에서 변수(식별자)를 찾고 해당 스테이지에 식별자가 없을 때 상위 지역으로 올라가서 검색을 한다. 그렇게 쭉쭉 올라가다 전역변수에도 식별자가 없으면 reference에러를 발생시킨다.

이 때문에, 하위 스코프에서 선언된 변수는 참조할 수 없는 것임.

함수 레벨 스코프

자바스크립트만의 중요한 특징이 있다.
자바스크립트 속 지역은 '함수 몸체'를 말한다. 단순한 {} 코드 블록은 지역스코프가 생성되지 않는다!

C나 자바 대부분의 프로그래밍 언어는 모든 코드블록이 지역스코프를 만든다.

하지만, 자바스크립트 속 var로 선언된 변수는 오로지 함수의 블록만을 지역 스코프로 인정한다. 이러한 특성을 함수 레벨 스코프라 한다.

따라서 if문 속 변수나 for문 속 코드블록에서 선언된 변수는 모두 전역변수 취급되어 외부 값이 재할당되어 변동될 수 있다.

var i = 10;
for (var i = 0; i <5 ; i++) {
	console.log(i);
}
console.log(i); //5	
var x = 1;
if (true) {
	var x = 10;
}
console.log(x); //10

렉시컬 스코프

-> 함수를 어디서 호출했는가가 아닌! 함수를 어디서 정의했는가에 따라 상위스코프를 결정한다!!!

profile
FE 개발자 준비생 블로그 🪐

0개의 댓글