문제점: 동일한 이름의 변수가 이미 선언되어 있는지 모르고 중복 선언 & 값까지 할당할 경우 먼저 선언된 변수 값이 변경되는 부작용 발생
var x = 1;
var y = 1;
// 같은 스코프 내에서 중복 선언 허용 (에러 발생 x)
// 초기화문이 있는 변수 선언문: js 엔진에 의해 var 키워드가 없는 것처럼 동작
var x = 100;
// 초기화문이 없는 변수 선언문: 무시됨
var y;
console.log(x); // 100
console.log(y); // 1
오로지 함수의 코드 블록만을 지역 스코프로 인정
if문, for문 내에서 선언하면 모두 전역 변수가 됨
문제점: 전역 변수를 남발할 가능성을 높임 → 의도치 않게 전역 변수가 중복 선언되는 현상 발생
var x = 1;
if (true) {
var x = 10;
}
console.log(x); // 10
변수 선언문이 스코프의 맨 앞으로 끌어 올려져서 동작
→ 선언문 이전에 참조할 수 있게 됨
에러가 발생하지는 않지만, 가독성을 떨어뜨리고 오류를 발생시킬 여지를 남김
// 변수 호이스팅에 의해 foo 변수 선언 (1. 선언 단계)
// undefined로 초기화 (2. 초기화 단계)
console.log(foo); // undefined
// 변수에 값 할당 (3. 할당 단계)
foo = 123;
console.log(foo); // 123
// 변수 선언은 런타임 이전에 js 엔진에 의해 암묵적으로 실행됨 (값 할당은 소스코드가 순차적으로 실행되는 런타임에 실행됨!)
var foo;
+) 호이스팅
var
로 선언한 변수의 경우 호이스팅 시 undefined
로 변수를 초기화합니다. 반면 let
과 const
로 선언한 변수의 경우 호이스팅 시 변수를 초기화하지 않습니다. (참고: 호이스팅)var bar = 123;
var bar = 456; // SyntaxError: Identifier 'bar' has already been declared
모든 코드 블록(if문, for문, while문 등)을 지역 스코프로 인정
let foo = 1; // 전역 변수
if (true) {
let foo = 2; // 지역 변수
let bar = 3; // 지역 변수
}
console.log(foo); // 1
console.log(bar); // ReferenceError: bar is not defined
console.log(foo); // ReferenceError: foo is not defined
let foo;
console.log(foo); // undefined
foo = 10;
console.log(foo); // 10
const TAX_RATE = 0.1;
)객체는 원시값과 달리 재할당 없이도 직접 변경이 가능하기 때문 → 참조값은 변하지 않음
const person = { name: 'Lee', age: 20 }
person.name = 'Won';
console.log(person); // { name: 'Won', age: 20 }