- 프로그래밍 언어에는 스코프(scope)라는 개념이 사용된다. 쉽게 말해, 모든 식별자는 선언된 위치에 따라 자신의 값을 참조할 수 있는 유효 범위가 존재한다는 것이다. JavaScript에서는 전역 스코프와 지역 스코프로 크게 나눌 수 있으며, 지역 스코프에는 함수 스코프와 블록 스코프가 있다.
- JavaScript에서 변수는 선언 → 초기화 → 할당 과정을 거쳐서 사용되며, 선언 키워드에는 var, let, const가 있다.
- const가 let 키워드와 다른 점은 선언과 동시에 초기화를 반드시 진행해야 하는 것과 재할당이 불가능하다는 것이다.
- JavaScript에는 컴파일 단계에서 변수와 함수의 선언이 해당 스코프 내 최상단으로 끌어올려져 동작되는 호이스팅(Hoisting) 개념이 존재한다.
-
ES5(ECMAScript5)에서 도입된 변수 키워드
-
함수 스코프를 따름
function testVar() { if (true) { var x = 1; } console.log(x); // 1 출력 } testVar();
-
전역 스코프에서 지정한 변수가 전역 객체(window, global) 속성으로 접근 가능함
var globalVar = 'var'; console.log(window.globalVar); // "var" 출력 console.log(globalVar); // "var" 출력
-
같은 변수명으로 재선언 가능
var x = 10; console.log(x); // 10 출력 var x = 20; // 에러 없이 재선언 가능 console.log(x); // 20 출력
-
호이스팅 결과로 선언 전 참조 시 undefined 출력
console.log(a); // undefined var a = 5;
-
ES6(ECMAScript2015)에서 도입된 변수 키워드
-
블록 스코프를 따름
function testLet() { if (true) { let y = 1; } console.log(y); // ReferenceError: y is not defined } testLet(); // 블록 밖에서 y를 찾을 수 없기 때문에 참조 에러 발생
-
전역 스코프에서 지정한 변수가 전역 객체 속성으로 접근 불가능함
let globalLet = 'let'; const globalConst = 'const'; console.log(window.globalLet); // undefined console.log(window.globalConst); // undefined console.log(globalLet); // "let" 출력 console.log(globalConst); // "const" 출력
-
같은 변수명으로 재선언 시 에러 발생
let y = 10; let y = 20; // SyntaxError: Identifier 'y' has already been declared
-
호이스팅 결과로 선언 전 참조 시 참조 에러 발생
console.log(b); // ReferenceError: b is not defined let b = 5;
-
TDZ(Temporal Dead Zone, 일시적 사각지대)
- 선언 단계 : let 키워드를 사용해 변수를 선언하였을 경우, 호이스팅되지만 변수 초기화가 일어나지 않았기 때문에 TDZ에 들어감
- TDZ : 변수 a가 선언되었지만 초기화되지 않은 상태로 참조하려고 할 경우 ReferenceError 발생함
- 초기화 및 할당 단계 : 런타임 단계에서 let a = 10; 문장이 실행되며 변수 a가 초기화되고 값 10이 할당되며 TDZ에서 벗어났기 때문에 참조할 수 있음
- 함수 스코프보다 블록 스코프가 변수의 사용 범위를 세밀하게 설정할 수 있기 때문에 변수 충돌을 방지함
- 변수의 유효 범위를 특정 블록 내부로 제한하기 때문에 코드의 가독성이 높아지고 유지보수가 쉬워짐
- 블록 스코프의 경우, 변수가 필요 없는 시점에 자동으로 메모리에서 해제될 수 있기 때문에 메모리 관리 효율성 측면에서 좋음
- TDZ의 존재로 초기화되지 않은 변수를 참조할 수 있는 var 키워드의 호이스팅으로 인한 오류를 방지할 수 있음