함수 안에 있는 선언들을 모두 끌어 올려서 해당 함수 유효 스코프의 최상단에 선언 하는 것을 말한다.
(var 선언문이나 function 선언문 등을 해당 스코프의 선두로 옮긴 것처럼 동작하는 특성)
var 변수 선언과 함수선언문에서만 호이스팅이 일어난다.
var 변수/함수의 선언만 위로 끌어 올려지며, 할당은 끌어 올려지지 않는다.
let/const 변수 선언과 함수표현식에서는 호이스팅이 발생하지 않는다.
👉var , let , const 키워드로 선언된 변수는 선언 부분만 끌어올려진다고 생각할 수 있다. 따라서 var 의 경우에는 변수 선언전에도 참조할 수 있지만 할당을 하지 않았기에 undefined 이다.
: 식별자가 호이스팅 후 실제 코드에서 선언되기 전까지 TDZ(Temporal Dead Zone/일시적 사각지대)에 있기 때문에 let, const 선언코드가 있는 곳 이전에는 해당 변수에 참조할 수 없게 된다.
참조 오류가 나는 구간인 스코프 시작지점부터 초기화 지점까지의 구간.
초기화가 되기 전까지는 TDZ라는 곳에 머물러서 초기화(혹은 할당)이 될 때까지 잠시 '죽어있는 상태'이기 때문에 선언 전에 참조가 불가능한 것.
선언 전에 변수를 사용하는 것을 비허용하는 개념상의 공간이다.
console.log(a); // undefined
f1(); // undefined
console.log(f2) // undefined
f2(); // TypeError: f2 is not a function
function f1(){
console.log(b);
var b = 5;
}
var f2 = function () {
console.log(c);
var c = 7;
}
var a = 10;
코드 해석
var a; //초기화 된 전역변수
function f1(){
var b; //초기화 된 지역변수
console.log(b);
b = 5;
}
var f2;
console.log(a);
f1();
console.log(f2);
f2();
f2 = function f2() {
var c; //초기화된 지역변수
console.log(c);
c = 7;
}
a = 10;
호이스팅 시 function 안에서 쓴 것 빼고는 전부 전역변수라고 생각하면 된다!
참고로 const , let 말고도 class 구문과 클래스의 constructor() 내부의 super(), 기본 함수 매개변수도 TDZ 제한이 있다. 반면 var , function 구문은 TDZ에 영향을 받지 않으며 현재 스코프에서 호이스팅이 된다.
변수나 함수에 접근할 수 있는 위치를 말한다.
ex)
function foo() {
var x;
}
👉위의 예시에서 x의 스코프는 함수 foo() 이다.
: 정적 스코프(Static scope), 렉시컬 스코프(Lexical scope)라고도 불리며, 프로그램을 실행하지 않고 소스 코드에 존재하는대로 해석한 스코프이다.
: 어휘적(정적)으로 지정되며, 즉 프로그램의 정적 구조를 보면 변수의 스코프를 판단할 수 있고 함수를 어디서 호출했는지 등에 영향을 받지 않는다.
또한 변수 스코프는 함수이며, 함수만이 새 스코프를 도입할 수 있다.
스코프가 변수의 스코프 안에 중첩되어 있으면 그 변수는 해당 스코프 전체에서 접근할 수 있다.
ex)
function foo(arg){
function bar(){ //중첩 스코프 bar()
console.log(`Hi, ${arg}`);
}
bar();
}
foo("jacob"); //Hi, jacob
: 내부 스코프에서 외부 스코프에 있는 변수와 이름이 같은 변수를 선언하면, 내부 스코프와 그 안에 중첩된 모든 스코프는 외부 스코프의 이름이 같은 변수에 접근할 수 있다.
내부 변수가 바뀌어도 외부 변수는 바뀌지 않으며, 내부 스코프에서 빠져나가면 다시 접근할 수 있다.
ex)
var x = "global";
function f(){
var x = "local";
console.log(x); // local
}
f(); // local
console.log(x); // global