호이스팅(Hoisting)과 TDZ,Scope

이진희·2022년 5월 17일
0

개념정리

목록 보기
2/10
post-custom-banner


📌 호이스팅이란

함수 안에 있는 선언들을 모두 끌어 올려서 해당 함수 유효 스코프의 최상단에 선언 하는 것을 말한다.
(var 선언문이나 function 선언문 등을 해당 스코프의 선두로 옮긴 것처럼 동작하는 특성)

📍호이스팅의 대상

var 변수 선언과 함수선언문에서만 호이스팅이 일어난다.
var 변수/함수의 선언만 위로 끌어 올려지며, 할당은 끌어 올려지지 않는다.
let/const 변수 선언과 함수표현식에서는 호이스팅이 발생하지 않는다.

👉var , let , const 키워드로 선언된 변수는 선언 부분만 끌어올려진다고 생각할 수 있다. 따라서 var 의 경우에는 변수 선언전에도 참조할 수 있지만 할당을 하지 않았기에 undefined 이다.


📍let/ const 가 호이스팅이 발생하지 않는 이유

: 식별자가 호이스팅 후 실제 코드에서 선언되기 전까지 TDZ(Temporal Dead Zone/일시적 사각지대)에 있기 때문에 let, const 선언코드가 있는 곳 이전에는 해당 변수에 참조할 수 없게 된다.


📌Temporal Dead Zone(TDZ)

참조 오류가 나는 구간인 스코프 시작지점부터 초기화 지점까지의 구간.
초기화가 되기 전까지는 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;
  • 지역변수 : Block{}안에서 선언된 변수. Block 안에서만 쓸 수 있음.
  • 전역변수 : Block{}밖에서 선언을 한 어디서든 쓰일 수 있는 변수

호이스팅 시 function 안에서 쓴 것 빼고는 전부 전역변수라고 생각하면 된다!

참고로 const , let 말고도 class 구문과 클래스의 constructor() 내부의 super(), 기본 함수 매개변수도 TDZ 제한이 있다. 반면 var , function 구문은 TDZ에 영향을 받지 않으며 현재 스코프에서 호이스팅이 된다.


📌스코프(Scope)

변수나 함수에 접근할 수 있는 위치를 말한다.

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

📍Shadowing

: 내부 스코프에서 외부 스코프에 있는 변수와 이름이 같은 변수를 선언하면, 내부 스코프와 그 안에 중첩된 모든 스코프는 외부 스코프의 이름이 같은 변수에 접근할 수 있다.
내부 변수가 바뀌어도 외부 변수는 바뀌지 않으며, 내부 스코프에서 빠져나가면 다시 접근할 수 있다.

ex)

var x = "global";
function f(){
  var x = "local";
  console.log(x);  // local
}
f(); // local
console.log(x); // global
post-custom-banner

0개의 댓글