JavaScript

[JavaScript] 스코프(Scope)와 변수 var, let, const

jane.dev 2021. 9. 3. 00:21
반응형
스코프(Scope)
유효범위를 의미하는 것으로,
자바스크립트에서는 전역 스코프(Global scope),
지역 스코프 혹은 함수 레벨 스코프(Local scope or Function-level scope)로 나눔

 

 

전역 스코프 전역 변수가 가지는 스코프로, 코드 어디에서든지 참조 가능
지역 스코프 지역(함수)내에서 선언된 변수가 가지는 스코프이며 함수 코드 블록이 만든 스코프로, 함수 자신과 하위 함수에서만 참조 가능

→ 이렇게 변수는 선언 위치에 따른 스코프를 갖게됨

 

JavaScript 는 블록 레벨 스코프(Block-level Scope)를 따르는 다른 언어들과 달리, 함수 레벨 스코프(Function-level scope) 를 따름

블록 레벨 스코프

모든 코드 블록(함수를 비롯한 if문, for문, while문, try ~ catch 문 등) 내에서 선언된 변수는 코드 블록 내에서만 유효하며,

코드 블록 외부에서 참조할 수 없음

함수 레벨 스코프

함수 내에서 선언된 변수는 함수 내에서만 유효(접근이 가능)하며 함수 외부에서 참조할 수 없음

 

var let const
Function-level scope Block-level scope Block-level scope

ES6 이전까지 JavaScript 에는 함수 레벨 스코프를 가지는 var라는 키워드의 변수만 있었는데, 

ES6 이후 블록 레벨 스코프를 가지는 let, const 변수 선언 키워드가 등장함

 

기존의 var 키워드의 변수가 가지는 문제점

1. 변수 중복 선언 허용

var a = 1;
var a = 2;	// 재선언 가능
a = 3;		// 재할당 가능

let b = 1;
let b = 2;	// 재선언 불가능
b = 3;		// 재할당 가능

const c = 1;
const c = 2;	// 재선언 불가능
c = 3;		// 재할당 불가능

 

2. 함수 레벨 스코프

var a = 1;
if(true){
    var a = 10;
}
console.log(a);	// 출력값: 10

let b = 1;
if(true){
    let b = 10;
}
console.log(b);	// 출력값: 1

const c = 1;
if(true){
    const c = 10;
}
console.log(c);	// 출력값: 1

var는 함수의 코드 블록만 스코프로 인정하므로

if 문 외부에서 선언된 a 가 존재하지만, if 문 내부에서 a 변수를 재선언해도 해당 변수를 if 문 내부의 지역변수가 아닌 전역변수로 간주

→ 메모리 누수, 디버깅이 어려우며 가독성이 떨어짐

 

3. 변수 호이스팅(hoisting)

console.log(a);	// undefined
a = 1;		// 할당은 이 자리 그대로
console.log(a);	// 1
var a;

// let과 const는 호이스팅이 일어나지 않음
console.log(b);	// error, Cannot access 'b' before initialization, 초기화되기전에는 접근불가
b = 1;
console.log(b);	
var b;

console.log(c);	
c = 1;
console.log(c);	
var c;		// error, Missing initializer in const declaration, 초기화해야함

아래에 위치한 것을 끌어올린다는 의미로, 실행전 변수 선언과 할당 내용에서 선언 부분을 분리하여 가장위로 끌어올림

→ 선언과 초기화와 출력의 순서가 어떻든 작동하며 프로그램의 논리적 흐름을 방해