function outerFunction() {
var outerVariable = "I'm outer variable";
function innerFunction() {
var innerVariable = "I'm inner variable";
console.log(outerVariable); // outerVariable 출력 가능
console.log(innerVariable); // innerVariable 출력 가능
}
innerFunction();
console.log(outerVariable); // outerVariable 출력 가능
console.log(innerVariable); // ReferenceError: innerVariable is not defined
}
outerFunction();
outerFunction
내에 존재하는 변수 및 함수 => outervariable
innerFunction
innerFunction
내에 존재하는 변수 => innerVariable
위 코드를 보면 innerFunction
함수를 outerFunction
내에서 호출하고 있으며 이 때 innerFunction
함수는 스코프체인의 첫 지점이기 때문에 모든 변수를 참조 가능하다. 그리고 outerFunction
에서는 innerFunction
의 지역변수를 참조하려 하고 있다. 그러나, 앞서 말했다 시피 지역변수의 생명주기는 함수의 생명주기와 일치한다. 그렇기 때문에 참조 에러가 발생한다.
=> var로 선언한 변수는 전역 객체의 프로퍼티가 된다. 이는 전역객체의 생명주기와 전역 변수의 생명주기가 일치하다는 것을 뜻한다.
var는 쓰지말자.
지역 변수 선언을 생활화 합시다.
var x=1;
if(true){
var x=10;
}
console.log(x); //10
{
, }
로 감싸져 있는 것을 블록 레벨 스코프 라고 부른다. var는 함수스코프만 따르기 때문에 위와 같은 코드에서 중복선언으로 인식돼 암묵적 결합이 일어나 재할당이 되어버린다..let x=1;
{
//TDZ - Temporal Dead Zone
let x=2;
let y=3
}
console.log(x); // 1
console.log(y); //y is not defined
var와 다르게 let과 const로 선언한 변수는 함수스코프를 포함한 모든 블록레벨스코프를 따른다. 또한 중복선언이 불가능하며, const로 선언한 변수는 재할당도 불가능하다.
호이스팅이 일어나지 않는 것처럼 보이지만 모두 런타임 이전에 호이스팅이 일어나며 var처럼 메모리공간을 확보하여 undefined로 초기화를 하진 않는다. 런타임 이전에 호이스팅이 일어나면서 자바스크립트 엔진 내에서 존재만 파악한다고 이해하면 쉽다. 또한 변수선언문 이전에 그 변수를 참조하려고 하면 Cannot access before Initialization
이라는 에러가 출력된다. 선언문 전에 참조할 수 없다 라는 에러 자체가 호이스팅이 되었다는 증거이고 이렇게 블록레벨스코프 최상단에선 선언한 지역변수를 참조할 수 없다 이러한 지역을 TDZ(Temporal Dead Zone) 이라고 부른다!
var 다신 보지말자.
재할당이 필요한 경우에만 let을 쓰자.
const 쓰자.