hoisting | 변수 재선언 | 변수 재할당 | 함수레벨 스코프 | 블록레벨 스코프 | 글로벌 스코프 | |
---|---|---|---|---|---|---|
var | O | O | O | O | X | O |
let | X | X | O | O | O | X |
const | X | X | X | O | O | X |
*
let, const에서의 hoisting(x): 정확히는 변수의 선언은 인지되나 값의 초기화, 할당은 되지 않은 상태 (var는 선언, 초기화까지된 상태)
console.log(coockie)
var coockie = 'red'
//undefined :호이스팅
console.log(subway)
let subway = 'egg'
//Uncaught ReferenceError: subway is not defined
console.log(coffee)
const coffee = 'americano'
//Uncaught ReferenceError: coffee is not defined
var는 hositing이 되면서 undefined라는 값을 반환하였고
let, const의 경우 참조에러를 나타낸다. 이 둘은 스코프가 시작되고 변수에 값이 할당되기 전까지 TDZ에 빠지기 때문이다.
*
Temporal Dead Zone (TDZ): 일시적 사각지대
1단계) 선언 - 변수를 실행컨텍스트의 변수객체에 등록, 스코프가 참조하는 대상
2단계) 초기화 - 선언된 변수에 대한 메모리 공간확보,undefined
로 초기화 된다.
3단계) 할당 -undefined
=>실제 값
으로 할당된다.
var는 변수의 선언과 초기화가 동시에 발생한다.💥
선언과 동시에 undefined
가 기본값으로 초기화되어 있는 상태여서
호이스팅될 때 undefined를 반환하게 된다.
let, const는 선언과 초기화가 분리되어 진행된다.💥 때문에 변수 선언문 이전에 변수에 접근하면 초기화되있지 않아 참조에러가 발생하는 것이다. 즉, 스코프의 시작(선언)지점부터 초기화 시점 전까지 변수를 참조할 수 없으며 이 구간을 일시적 사각지대
라고 표현한다.
var cake = 5000
console.log(cake) //5000
var cake = 3000
console.log(cake) //3000 :재선언
let cafe = 'bonitto'
let cafe ='starbucks'
console.log(cafe)
//Uncaught SyntaxError: Identifier 'cafe' has already been declared
const ice_cream = '31'
const ice_cream ='merona'
console.log(ice_cream)
//Uncaught SyntaxError: Identifier 'ice_cream' has already been declared
var test = 50
test = 100
console.log(test) //100 :재할당
let interview = 'today';
interview = 'yesterday';
console.log(interview)
//'yesterday'
const pass = true;
pass = false;
console.log(interview)
//Uncaught TypeError: Assignment to constant variable.
//true
Global Scope : browser - window
, Node.js - global
var로 변수를 선언하면 전역객체의 프로퍼티로 받아들인다.
var a = 3
console.log(a) //3
console.log(window.a) //3
let b = 5
console.log(window.b) //undefined
var 변수선언은 함수 내부에 작성하는 경우가 아니라면, 전역 스코프에 속한다. 아래는 함수가 아닌 전역의 일반 블록 내에 선언되어 있는 상태이다. 전역 스코프의 변수로 인식된다. (*
아래 블록레벨스코프 참고)
if (true) {
var x = 5;
}
console.log(x); //5
(Function-level-scope)
변수가 var, let, const 에 상관없이 모두 함수 단위에서만 유효하다.
(function () {
var x = 5;
})();
console.log(x); // Uncaught ReferenceError: x is not defined
(Block-level-scope) : let
, const
중괄호로 구문의 경계를 구분
let, const의 경우에만 해당 블록에서 유효한 변수값을 갖게 된다.
함수레벨스코프, 블록레벨 스코프의 특성을 모두 가지면서
let, const가 동일 변수를 재선언할수 없어 매번 새로운 변수를 만들어 내야하는 문제를 해결해 준다.
동일 함수 내에서만 유일한 변수명을 가지면 된다.
if (true) {
let x = 5;
}
console.log(x)
//Uncaught ReferenceError: x is not defined
(Non-Block-level-scope) : var
if (true) {
var x = 5;
}
console.log(x); //5
var는 함수 레벨 스코프만 적용되어, 함수형태가 아닌 일반 블록의 변수값을 참조할 수 있다. 함수 내부가 아닌 전역 스코프에 변수가 선언된 상태이다.