만약 동일한 이름의 변수가 이미 선언되어 있는 것을 모르고 변수를 중복 선언하면서 값까지 할당했다면 의도치않게 먼저 선언된 변수 값이 변경되는 부작용이 발생
var x = 1;
var y = 1;
var x = 100;
var y;
console.log(x); //100
console.log(y); //1
var x = 1;
if(true){
//이미 선언된 전역 변수 x가 있으므로 x 변수는 중복 선언됨
var x = 10;
}
console.log(x) //10
//이 시점에는 변수 호이스팅에 의해 이미 foo 변수가 선언 (1.선언 단계)
//변수 foo는 undefined로 초기화 (2. 초기화 단계)
console.log(foo) //undefined
//변수에 값을 할당 (3. 할당 단계)
foo = 123;
console.log(foo) //123
//변수 선언은 런타임 이전에 자바스크립트 엔진에 의해 암묵적으로 실행
var foo;
변수 선언문 이전에 변수를 참조하는 것은 호이스팅에 의해 에러 발생 X, 가독성을 떨어뜨리고 오류를 발생시킬 여지를 남김
//var 키워드로 선언된 변수는 같은 스코프 내에서 중복 선언을 허용
var foo = 123;
var foo = 456;
//let, const 키워드로 선언된 변수는 같은 스코프 내에서 중복 선언을 허용하지 X
let bar = 123;
let bar = 456; //SyntaxError: Identifier 'bar' has alreay been declared
let foo = 1; //전역 변수
{
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 = 1; //할당문에서 할당 단계가 실행
console.log(foo); //1
그래서 호이스팅이 발생하지 않는가 ?
- 놉. 자바스크립트는 ES6에서 도입된 let, const를 포함해 모든 선언을 호이스팅
- 단, ES6에서 도입된 let, const, class를 사용한 선언문은 호이스팅이 발생하지 않는 것처럼 동작
let foo = 1; //전역 변수
{
console.log(foo); //ReferenceError: Cannot access 'foo' before initialization
let foo = 2; //지역 변수
}
// 전역 변수
var x = 1;
// 암묵적 전역
y = 2;
// 전역 함수
function foo(){}
// var 키워드로 선언한 전역 변수는 전역 객체 window의 프로퍼티다.
console.log(window.x); // 1
// 전역 객체 window 의 프로퍼티는 전역 변수처럼 사용할 수 있다.
console.log(x); // 1
// 암묵적 전역은 전역 객체 window의 프로퍼티다.
console.log(window.y); // 2
console. log (y); // 2
// 함수 선언문으로 정의한 전역 함수는 전역 객체 window의 프로퍼티다.
console.log(window.foo); // f foo() {}
// 전역 객체 window의 프로퍼티는 전역 변수처럼 사용할 수 있다.
console.log(foo); // f foo() (}
window.
와 같이 접근할 수 없음