ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 호이스팅과 var/let/const 차이점
    JS 2025. 11. 20. 15:27

     

     

    👇 예전에 클로저와 스코프에 대해 간단히 적었던 글이 있었다 

    2025.08.12 - [JS] - 클로저와 스코프

     

    클로저와 스코프

    나의 최애동료 지유님이 추천해준 일주일에 한번씩 기술면접을 위한 질문을 메일로 보내주는 매일메일을 알게되었다!첫 질문부터 모르는 질문이여서 당황스럽긴한데 뭐 당연한걸수도,,(이제

    lyla-bae.tistory.com

     

     

    간단하게 다시 설명하면 

    스코프는 유효범위, 클로저는 함수가 종료되더라도 그 유효범위(스코프)를 기억해놓는 열쇠같은 함수 라고 했다.

     

    오늘 호이스팅을 배우면서 떼놓을수 없는 개념들이기에 리마인드하면서

    오늘 배운 개념들을 다시 정리해보고자 한다

     


    호이스팅이란

    변수와 함수 선언이 코드 실행전에 해당 스코프의 최상단 1빠로 끌어올려지는 현상을 말한다.

     

    근데 여기서 주의해야할것은

    다 올라가는건 아니고 ‼️선언만 올라간다‼️

    console.log(name); // undefined
    var name = "철수";
    console.log(name); // "철수"

     

    이 코드가 에러없이 실행되는 이유는 사실 아래와 같기때문 🔻

    var name;          // 선언이 위로!
    console.log(name); // undefined
    name = "철수";     // 할당은 원래 자리
    console.log(name); // "철수"

     

     

    ⚠️ 그리고 함수표현식도 주의해야한다 왜냐면

    sayBye(); // ❌ TypeError: sayBye is not a function
    
    var sayBye = function() { //이렇게 변수에 할당하는것을 함수표현식이라 함
      console.log("안녕히가세요!");
    };

     

    여기서 함수는 변수에 할당하는 것때문에 타입에러가 뜨기때문,  실상 아래와 같이 읽히게 된다🔻

    var sayBye;        // 선언만 위로
    sayBye();          // undefined() 를 호출하려고 해서 에러!
    sayBye = function() {
      console.log("안녕히가세요!");
    };

     

     

     

    var vs let vs const의 차이

    정말 면접에서 단골질문으로 나오는걸로 유명한 개념들이라 예전에도 차이점에 대해 많이 보긴했는데

    재선언이 되느냐 안되느냐, 재할당이 되느냐 안되느냐에만 포커스에 꽂혔던거같다

    알고보니 스코프의 차이도 있다는 것!!

     

     

    var은 함수 단위로 스코프가 생긴다

    function test() {
      if (true) {
        var x = 1;
      }
      console.log(x); // 1이 나옴 - if 블록 밖에서도 접근 가능!
    }
    
    test();

     

    if나 for문 안에다 선언해도 함수안에서는 자유의 영혼이 되어버린다,,,

     

    반면 let/const는 {} (중괄호) 단위로 스코프가 생긴다

    function test() {
      if (true) {
        let y = 1;
        const z = 2;
      }
      console.log(y); // ❌ ReferenceError
      console.log(z); // ❌ ReferenceError
    }
    
    test();

     

    여기서 중괄호는 고급지게 블록단위로 스코프가 생긴다고 말할수도 있따,

     

     

    TDZ (Temporal Dead Zone)

    호이스팅에서 주의할점이 선언전에 let/const 변수에 접근하려고 하면 에러가 나게되는데

    스코프시작부터 변수 선언까지의 구간, 사각지대를 TDZ라고 한다.

    {
      // TDZ 시작
      // name을 사용할 수 없는 구역
      
      console.log(name); // ❌ 에러!
      
      let name = "영희"; // TDZ 끝, 이제부터 사용 가능
      console.log(name); // ✅ "영희"
    }

     

    TDZ가 생긴 이유는 var의 문제에서 시작됐는데....

    var는 선언전에 사용해도 undefined만 나오고 에러가 나지 않아서

    나중에 코드가 길어지면 어디서 실수를 했는지 찾기 힘들기때문에

    이 문제를 해결하기 위해 ES6에서 let/const가 생겼고,  TDZ란 개념도 자연스럽게 생긴것이당

     

     

    var의 또다른 문제점

    for (var i = 0; i < 3; i++) {
      setTimeout(function() {
        console.log(i);
      }, 100);
    }
    // 예상: 0, 1, 2
    // 실제: 3, 3, 3 😱

     

    여기서 보통 예상되는 i의 값은 0,1,2라 생각하는데 실제론 3이 3번반복된다.

    var로 i를 선언했기 때문에 변수 i는 함수스코프를 가지게되고,

    비동기함수(setTimeout)를 기다리는동안 이미 반복문을 마친 i는 3이 되어버리는것이다,,,

    뭔말인지 모르겠으면 아래코드를 참고하자🔻

    // 실제로는 이렇게 동작하는 것과 같다
    var i;
    for (i = 0; i < 3; i++) {
      setTimeout(function() {
        console.log(i); // 모두 같은 i를 봄
      }, 100);
    }
    // 여기서 i는 3

     

    이 문제를 해결하려면 let으로 바꾸면 된다! 🔻

    for (let i = 0; i < 3; i++) {
      setTimeout(function() {
        console.log(i);
      }, 100);
    }
    // 0, 1, 2 ✅

     

    let은 블록스코프, 위에 말했듯이 {}로 스코프생성이 되기때무네

    반복할때마다 새로운 i가 만들어지기 때문이다. (i가 지역변수가 된다는말씀)

    실제로 아래처럼 동작하는것과 같다고 보면된다. 🔻

    {
      let i = 0;
      setTimeout(function() { console.log(i); }, 100); // 이 i는 0
    }
    {
      let i = 1;
      setTimeout(function() { console.log(i); }, 100); // 이 i는 1
    }
    {
      let i = 2;
      setTimeout(function() { console.log(i); }, 100); // 이 i는 2
    }

     

     

    const는 재할당이 불가하지만, 이런경우는 또 가능함

    const obj = { name: "철수" };
    obj = { name: "영희" }; // ❌ 에러! 재할당 불가
    
    obj.name = "영희";      // ✅ 가능! 객체 내부는 변경 가능
    obj.age = 20;           // ✅ 가능!

     

    const는 변수가 가르키는 참조를 바꾸지못하는거지, 객체나 배열 내부를 바꾸는건 ssap가능

     

     

     

    결론은

    var는 쓰지말자. 되도록이면 const를 이용하고 재할당이 필요할때만 let을 이용하셈

    변수 선언은 최상단에 적자. 아무리 호이스팅이 된다고 해도 에러나는 상황이 많음,,

    쓰지말라면 쓰지말자고 제발

     

Designed by Tistory.