[JavaScript] 변수와 호이스팅

so8san·2022년 10월 5일

JAVASCRIPT

목록 보기
2/8

변수

변수(Variable)는 프로그램에서 사용되는 데이터를 일정 기간 동안 기억하여 필요한 때에 다시 사용하기 위해 데이터에 고유한 이름인 식별자(identifier)을 제외한 나머지 값들(배열, 함수, 정규표현식 등)은 모두 객체이다. 또한 객체는 pass-by-reference(참조에 의한 전달)방식으로 전한다.
참고 poiemaweb.com

var

  • 현재는 쓰이지 않는 변수 선언 방식
  • 함수 레벨 유효 범위 (function-level scope)
  • 중복선언 가능
  • 호이스팅 발생
  • 전역 선언시 전역 객체의 속성으로 등록

const

  • 블록 레벨 유효 범위( Block-level scope ) block은 중괄호 {} 범위
  • 재할당 불가능
  • 중복 선언 불가능
  • 호이스팅 안됨
  • 전역 선언시 전역 객체의 속성으로 등록 안됨

let

  • 블록 레벨 유효 범위( Block-level scope ) block은 중괄호 {} 범위
  • 재할당 가능
  • 중복 선언 불가능
  • 호이스팅 안됨
  • 전역 선언시 전역 객체의 속성으로 등록 안됨

호이스팅

호이스팅이란 선언들을 모두 끌어 올려서 유효 범위의 최상단에 선언되는 것을 말한다. 가 아닌, 변수나 함수를 선언 이전에 사용할 수 있기 때문에 모두 끌어 올려지는 것 처럼 보이는 현상입니다.

왜 var만 호이스팅이 이루어 질까? 💡

결론부터 말하자면 호이스팅은 var, let, const 전부 이루어집니다
이유는 자바스크립트 엔진 동작의 특징 때문인데요

  • 코드를 실행하기 전 실행 가능한 코드를 형상화 하고 구분하는 과정
  • 코드를 실행하기 전 실행 컨텍스트를 위한 과정에서 모든 선언들을 메모리에 저장
  • 코드 실행 전 이미 변수/함수 선언이 메모리에 저장되어 있기 때문에 선언문보다 참조/호출이 먼저 나와도 오류 없이 동작.
  • 따라서 이는 선언 파일의 맨 위로 끌어올려진 것 처럼 보이게 함.

여기서 const,let과 var가 다른 부분은 var는 실행컨텍스트가 생성될 때, 변수 객체에 배열 식별자 정보를 담는 variable 배열에 변수들을 먼저 담습니다. 먼저 담기 때문에 선언을 나중에 해도 사용이 가능한 것입니다. var선언과 동시에 AllocateTo 메소드를 통해 메모리에 바로 할당이 됩니다. 하지만 constletset_initializer_position 메소드를 통해 해당 코드의 position을 정해주어 초기화 해주는 과정을 거칩니다. 즉, TDZ에 빠집니다 따라서 var와 const,let은 선언 단계에서의 차이점이 있습니다.

var 키워드 변수는 선언 이전에 선언 단계와 초기화 단계를 동시에 진행하고,
let은 선언단계와 초기화 당계가 분리되어 진행이 됩니다. 그렇기 때문에 실행 컨텍스트에 변수를 등록했지만, 메모리가 할당이 되질 않아 접근할 수 없어 참조 에러(ReferenceError)가 발생하는 것 입니다.

TDZ 💡

호이스팅이 어떻게 이루어 지고 무엇인지 알기 이전에 TDZ를 간략하게 알고 가는 것이 이해하는데 도움이 됩니다. TDZ는 Temporal Dead Zone의 약어로 직역하면 일시적인 사각지대라는 뜻입니다. 스코프의 시작 지점부터 초기화 시작 지점까지의 구간을 TDZ 라고 합니다. 스코프의 시작 지점부터 초기화 시작 지점까지의 구간은 변수 선언의 3단계를 참고하세요.

변수 선언의 3단계 💡

  • 선언 단계 Declaration Phase
    • 변수를 실행 컨텍스트의 변수 객체에 등록.
    • 이 변수 객체는 스코프가 참조하는 대상이 됨.
  • 초기화 단계 Initialization phase
    • 변수 객체에 등록된 변수를 위한 공간을 메모리에 확보.
    • 이 단계에서 변수는 undefined로 초기화 됨.
  • 할당 단계 Assignment phase
    • undefined로 초기화된 변수에 실제 값을 할당.
    • var 키워드로 선언한 변수는 선언 단계와 초기화 단계가 한번에 이루어짐.
    • let키워드로 선언된 변수는 선언단계와 초기화 단계가 분리되어 실행된다. 
    • let, const의 경우 초기화는 코드 실행 후, 변수 선언문에 도달했을 때 이루어짐.따라서 초기화 이전에 변수 접근시 변수를 위한 메모리 공간이 확보되지 않았기 때문에 에러발생.

정리

호이스팅은 모든 변수 선언에서 이루어집니다.
또한, 호이스팅은 코드 실행 전, 변수/함수 선언이 파일의 맨 위로 끌어 올려진 것 같은 현상을 이야기 합니다.
var와 let,const의 차이점은 TDZ,변수 선언 단계에 있습니다.
var는 let,const와 다르게 선언과 동시에 메모리에 할당이 되고 let과 const는 초기화 과정을 거치기 때문에 var는 호이스팅된 상태를 그대로 보이지만, let,const는 호이스팅 되지 않은 것 처럼 보입니다.


🧠 생각

한번쯤은 깊게 알아보고 싶었던 주제였기에 정리 했지만, 사실 전부 이해하지 못했다. 더 자세히 깊게 알아본다면 이해하기 어렵겠지만 이정도에서 그친다면, 이해하기 어렵지 않을 것 같다. var는 선언과 동시에 메모리에 할당, let과 const는 뒤에 초기화 단계를 거치기 때문에 코드 실행 전 실행 컨텍스트를 위한 과정에서 모든 선언들을 메모리에 저장하는 자바스크립트 엔진 동작 특징에 벗어나서 참조에러를 일으킨다! 정도로 이해했다. scope에 관련된 내용을 먼저 적었어야 했으나... 건너 뛰어서 다음에는 scope관련 내용을 정리해 보려고 한다.

참고 https://share-factory.tistory.com/20

profile
늘 쌓아가는 중입니다.

0개의 댓글