모든 코드 블록(함수, if문, for문, while문 등) 내에서 선언된 변수는 코드 블록 내에서만 유효하다. 즉, 코드 블록 내부에서 선언한 변수는 지역 변수이며 코드 블록 외부에서는 참조할 수 없다.
함수 내에서 선언된 변수는 함수 내에서만 유효하며 이를 함수 외부에서 참조할 수 없다. 함수 내부에서 선언한 변수는 지역 변수이며 함수 외부에서 선언한 변수는 모두 전역 변수이다.
대다수의 프로그래밍 언어는 블록 레벨 스코프를 따르지만, 자바스크립트는 함수 레벨 스코프를 따른다.
var
키워드ES5까지만 해도, var
키워드는 변수를 선언하는 유일한 방식이었다.
1. 함수 레벨 스코프를 따른다
함수의 코드 블록만을 유일한 스코프로 인정한다. 따라서 함수 외부에서 선언된 모든 변수는 전역 변수로 취급된다. 또한 for문 안에서 선언한 변수를 for문 밖에서 참조할 수 있게 된다.
2. 키워드 생략이 가능하다
키워드를 생략하여 변수를 선언하면, 전역 변수가 지나치게 많아지는 문제가 발생한다.
3. 변수를 중복해서 선언할 수 있다
변수의 값이 의도하지 않았음에도 변경될 수 있다.
4. 선언문이 호이스팅된다
var
선언문의 호이스팅 방식에 따라, 변수를 선언하기 이전에 해당 변수를 참조할 수 있다.
var
키워드의 문제점
var
키워드는 전역 변수의 생성을 증가시킨다.
전역 변수는 간단한 애플리케이션의 경우, 사용이 간단하다는 편리함이 있다.
하지만 유효 범위(Scope)가 넓어 어디에서 사용될 것인지 파악하기가 힘들고, 의도치 않게 변경될 가능성(side effect)이 있어 코드의 복잡성을 증가시키기 때문에 무분별하게 사용해서는 안된다.
let
, const
키워드의 등장ES6는 이러한 var
키워드의 단점을 보완하고자, let
키워드와 const
키워드를 도입하였다.
let
키워드블록 레벨 스코프를 따르는 변수를 선언한다.
1. 블록 레벨 스코프를 따른다
let num = 123;
for(i = 0; i < 3; i++) {
num =
}
2. 변수를 중복해서 선언할 수 없다 (재할당은 가능)
let num = 123;
num = 456; // 재할당 가능
let num = 789; // Uncaught SyntaxError: Identifier 'bar' has already been declared
3. 선언문이 호이스팅된다
let
선언문의 호이스팅 방식에 따라, 변수를 선언하기 이전에 해당 변수를 참조할 수 없다.
4. 클로저
5. 전역객체(모든 객체의 유일한 최상위 객체)와 let
var
키워드로 생성된 전역 변수는 전역 객체의 프로퍼티가 되지만,
var num = 123;
console.log(window.num); // 123
let
키워드로 생성된 전역 변수는 전역 객체의 프로퍼티가 되지 않는다. let
전역 변수는 보이지 않는 개념적인 블록 내부에 존재하기 때문이다.
let num = 123;
console.log(window.num); // undefined
const
키워드const
키워드는 상수, 즉 변하지 않는 값을 선언할 때 주로 사용한다. 하지만 반드시 상수만을 위해 사용하는 키워드는 아니며 let
키워드와 대부분의 특징을 공유한다.
1. 선언과 초기화
let
키워드와 마찬가지로 블록 레벨 스코프를 따른다.
다만, const
키워드로 선언된 변수는 값의 재할당이 불가능하다. ( 반면, let
키워드는 재할당이 가능하다. )
let num1 = 123;
num1 = 456; // 재할당 가능
const num2 = 123;
num2 = 456; // TypeError: Assignment to constant variable.
또한, 선언과 초기화가 반드시 동시에 이루어져야 한다.
const num3; // 초기화 없이 선언만 할 경우 SyntaxError 발생
2. 상수
코드의 가독성과 유지보수의 편의를 위해서는, const
키워드를 통해 상수를 선언하여 사용하는 것이 중요하다.
let isAdult;
// 그냥은 알아보기 힘든 값 19
if (age >= 19) {
isAdult = true;
}
// 상수로 선언하고 변수명을 적절히 사용하면 코드의 가독성이 매우 높아진다
const minAge = 19;
if (age >= minAge) {
isAdult = true;
}
3. 객체와의 관계
const
키워드는 객체에도 사용할 수 있다. 마찬가지로 재할당은 금지된다. 이는 const
변수의 타입이 객체인 경우, 객체에 대한 참조를 변경할 수 없음을 의미한다.
하지만 해당 변수 객체의 프로퍼티는 보호되지 않으므로, 할당된 객체의 내용은 변경할 수 있다. (프로퍼티 추가, 삭제 또는 프로퍼티 값의 변경)
ES6를 사용한다면,
var
키워드는 가급적 사용하지 않는다.
변수 선언에는 기본적으로
const
키워드를 사용한다.
변수 값의 재할당이 필요한 경우에만
let
키워드를 사용한다.
이 때, 변수의 스코프(Scope)는 최대한 좁게 만든다.
원시 값의 경우, 가급적 상수를 선언하여 사용한다.
객체를 재할당하는 경우는 생각보다 드물다.
따라서,const
키워드 사용을 통해 의도치 않은 재할당을 방지한다.