
1-1) 변수 중복 선언 허용
var 키워드로 선언한 변수는 중복 선언이 가능하다.
이는 의도치 않게 값이 변경될 수 있는 위험이 있다.
var name = '철수';
console.log(name); // 철수
var name = '영희';
console.log(name); // 영희
// 아무런 에러가 발생하지 않고 다시 선언돼버린다
1-2) 함수 레벨 스코프
var는 '함수' 안에서만 지역변수로 인정되고, if문이나 for문 같은 다른 블록에서는 모두 전역변수가 된다.
// for문 예시 - 전역변수가 되어버림
var i = 10;
for (var i = 0; i < 5; i++) {
console.log(i); // 0, 1, 2, 3, 4
}
console.log(i); // 5
// for문의 i와 바깥의 i가 같은 변수가 되어버렸다
// if문 예시 - 전역변수가 되어버림
var value = 'hello';
if (true) {
var value = 'world'; // 위의 value를 덮어씌움
}
console.log(value); // 'world'
// 함수 예시 - 지역변수로 잘 동작함
function example() {
var local = '지역변수';
}
console.log(local); // ReferenceError: local is not defined
// 함수 안의 var는 지역변수라서 함수 밖에서 접근 불가
1-3) 변수 호이스팅
var로 선언한 변수는 선언문 이전에도 사용할 수 있다.
이를 변수 호이스팅이라고 한다.
값을 할당하기 전에는 undefined가 기본값으로 할당된다.
console.log(number); // undefined
var number = 10;
console.log(number); // 10
// 위 코드는 실제로 이렇게 동작한다:
var number; // 선언이 최상단으로 끌어올려진다
console.log(number);
number = 10;
console.log(number);
2. let 키워드
앞서 본 var의 단점을 보완하기 위해 es6에서는 let과 const를 도입한다.
2-1) 변수 중복 선언 금지
let은 var와 다르게 같은 이름의 변수를 두 번 선언하면 에러가 발생한다.
let name = '철수';
let name = '영희'; // 에러 발생! 같은 이름으로 또 선언할 수 없다
2-2) 블록 레벨 스코프
let은 중괄호({}) 안에서 선언하면 그 안에서만 사용할 수 있는 변수가 된다.
이는 함수, if문, for문 등 모든 중괄호에 적용된다.
let i = 10;
// for문 안에서 선언된 i는 for문 안에서만 사용되는 별개의 변수
for (let i = 0; i < 5; i++) {
console.log(i); // 0, 1, 2, 3, 4
}
console.log(i); // 10 (바깥의 i는 그대로 10을 유지)
// if문 예시
if (true) {
let message = '안녕하세요';
console.log(message); // '안녕하세요'
}
console.log(message); // 에러 발생! message는 if문 안에서만 사용 가능
2-3) 변수 호이스팅
let으로 선언한 변수는 선언하기 전에 사용할 수 없다.
이 부분이 var와의 가장 큰 차이점 중 하나다.
console.log(name); // 에러 발생! 변수를 선언하기 전에 사용할 수 없다
let name = '철수';
// 마치 이런 식으로 동작한다:
// 변수를 선언하기 전까지는 사용할 수 없는 구간이 있음 (이를 TDZ라고 함)
// let name; <- 이 시점부터 사용 가능
// name = '철수';
2-4) 전역 객체와 let
var로 선언한 전역 변수는 window라는 전역 객체의 속성이 되지만,
let으로 선언한 전역 변수는 그렇지 않다.
var varName = '철수';
let letName = '영희';
console.log(window.varName); // '철수'
console.log(window.letName); // undefined (window 객체에 속하지 않음)
3. const 키워드
const는 상수를 선언하기 위해 사용한다.
const는 let과 비슷하지만 몇 가지 중요한 차이점이 있다.
3-1) 선언과 초기화
const로 선언한 변수는 반드시 선언과 동시에 값을 할당해야 한다.
const name; // SyntaxError: Missing initializer in const declaration
const age = 20; // 올바른 선언
// let은 이렇게 해도 됨
let name;
name = '철수';
3-2) 재할당 금지
const로 선언한 변수는 한번 값을 할당하면 다른 값으로 바꿀 수 없다.
const age = 20;
age = 21; // TypeError: Assignment to constant variable
// let은 이렇게 가능
let age = 20;
age = 21; // 문제없음
3-3) 상수
const는 주로 변하지 않는 값을 선언할 때 사용한다.
상수는 보통 대문자로 작성하고, 여러 단어는 _로 구분한다.
const MAX_SPEED = 100;
const COMPANY_NAME = '테코';
const TAX_RATE = 0.1;
// 이렇게 하면 코드를 읽을 때 '아, 이건 변하지 않는 값이구나'라고 쉽게 알 수 있다
3-4) const와 객체
const의 재할당 금지는 조금 특별하게 동작한다:
- 숫자, 문자열 같은 기본 타입은 값을 전혀 변경할 수 없다
- 객체, 배열 같은 참조 타입은 내부 값을 변경할 수 있다
// 기본 타입 (값 변경 불가)
const name = '철수';
name = '영희'; // 에러 발생!
// 객체 (내부 값 변경 가능)
const person = {
name: '철수',
age: 20
};
person.name = '영희'; // 가능!
person.age = 21; // 가능!
// 하지만 객체 자체를 바꾸는 것은 불가능
person = { name: '영희', age: 21 }; // 에러 발생!
// 배열도 마찬가지
const numbers = [1, 2, 3];
numbers.push(4); // 가능!
numbers[0] = 10; // 가능!
numbers = [4, 5, 6]; // 에러 발생!
이러한 특징 때문에 const는 변하지 않아야 할 값을 보호하거나,
실수로 값이 바뀌는 것을 방지하고 싶을 때 주로 사용한다.
4. var vs let vs const
변수 선언에는 기본적으로 const를 사용하고
let은 재할당이 필요한 경우에 한정해 사용하는 것이 좋다.
객체는 의외로 재할당하는 경우가 드물기 때문에 일단 const를 사용해 선언한 뒤
나중에 필요하다면 let으로 변경해도 된다.
'JS' 카테고리의 다른 글
모던 자바스크립트 딥다이브 16장 - 프로퍼티 어트리뷰트 (0) | 2025.02.21 |
---|---|
모던 자바스크립트 딥다이브 14장 - 전역 변수의 문제점 (0) | 2025.02.19 |
모던 자바스크립트 딥다이브 13장 - 스코프 (0) | 2025.02.18 |
모던 자바스크립트 딥다이브 12장 - 함수 (0) | 2025.02.17 |
모던 자바스크립트 딥다이브 11장 - 원시 값과 객체의 비교 (1) | 2025.02.16 |