본문 바로가기
✏️ 공부/JavaScript

호이호이- (Hoisting)

by minzyee 2022. 5. 21.

사아아실... 호이스팅 글 정리하기는 예전에 알아보다가 (내 머리가 너무나 나빠서) 중간에 포기한 전적있다.
다시 해보려고 한다. 호이호이- 뾰로롱★

아기공룡 둘리

 

 

 

 


 

 

 

 

호이스팅이 뭔데?

호이스팅은 프로그래밍 중에 변수나 함수를 어디에 선언했는지에 상관 없이

유효범위 내 제일 최상단에 선언된 것처럼 끌어올려주는 것을 의미한다.

(이곳저곳 구글링을 했는데, 변수가 실제로 끌어올려져서 옮겨진게 아니라 끌어올려진 것처럼 보이는 거라고 하더라)

 

그래서 호이스팅 얘기를 왜 하냐구?

변수마다 호이스팅으로 인한 결과가 다른 것에 대해 이야기 할건데,
우선 변수 선언 키워드를 알아야함.

• var
• let
• const

var 나 let 은 "일단 이 값으로 해둘게요" 이런 느낌(변수 : 재할당이 가능한, 나중에 변할수도있는 값 이기 때문)
const 는 "이 값은 절대 변하면 안됨" 이런 느낌(상수)


자바스크립트가 ES6으로 업그레이드 되기 전엔
변수 생성 키워드로 var를 썼다고 함(이거 밖에 없었으니까)
근데 var 가 문제가 너무 많다고 함.

var 와 let 를 사용해 비교해보자면 아래 코드박스와 같다.
아래 처럼 코드를 짜면 에러가 나는 것이 당연한 것인데
var 를 쓰면 콘솔 출력이 잘 나옴...

// var의 경우
console.log("var 선언 첫번째 콘솔 : " + name1); // var 선언_첫번째 콘솔 : undefined
var name1 = 'minji'; // name1에 'minji'를 할당함
console.log("var 선언 두번째 콘솔 : " + name1); // var 선언_첫번째 콘솔 : minji


// let의 경우
console.log(name2); // Reference Error : 초기화 하기 전에 name2에 접근할 수 없음
let name2 = "minji";
console.log(name2);

바로 var 의 호이스팅 때문인데
"var의 선언 첫번째 콘솔"이 undefined가 나온 이유
선언(name1)은 호이스팅 되었지만, 할당(minji)은 호이스팅 되지 않았기 때문임
- var는 선언과 초기화(undefined를 할당하는 단계)가 동시에 이루어지기 때문에 에러가 나지않고 undefined가 출력 됨
var name1 = 'minji'; 라고 값이 할당된 후의 "var의 선언 두번째 콘솔"은 문제 없이 'minji' 라는 값이 잘 출력되어 나온다.

 

 

TDZ(Temporal Dead Zone)

let 이랑 const 도 호이스팅 발생하지만 var 와 다르게 제한이 있음
TDZ 때문인데 '일시적 사각지대'란 의미를 갖고있음

 

 

* 스코프 이미지 넣기

 

- TDZ는 스코프{ 시작 ~ 변수의 초기화가 진행되기 전 사이의 구간을 말함.
  (변수가 선언 되고 변수의 초기화가 이루어 지기 전 까지의 구간)
- TDZ 에서는 선언 되기 전이거나 초기화 되기 전인 상태의 변수를 사용하는 것을 허용하지 않음.
  그래서 TDZ 구간 때, 선언되지 않거나 초기화 전인 변수를 참조하게 되면 에러가 발생하게 됨.

  let 과 const 가 바로 이 영역의 영향을 받음

- "let의 첫번째 콘솔 출력" 에 Error가 난 것이 바로 let 이 호이스팅 된 것을 나타냄
   let 과 const 는 값을 할당 받기 전까진 사용 할 수 없음.

- 선언 단계에서 실행 컨텍스트에 변수를 등록은 했지만, 값이 할당되지 않아 접근 할 수 없어서 Reference Error 가 발생함.

  let과 const도 호이스팅은 되었지만 접근할 수가 없어서 호이스팅이 되지않은 것 처럼 보이는 거임.

// let의 경우
console.log("let의 첫번째 콘솔 출력: " + name2); // ReferenceError: 초기화 하기 전에 name2에 접근할 수 없음
let name2 = "minji";
console.log("let의 두번째 콘솔 출력: " + name2);



변수의 생성 과정

호이스팅은 변수의 생성 과정과 연관이 있음.


1. 선언 단계(Declaration phase)

    → 변수를 실행 컨텍스트의 변수 객체에 등록하는 단계

    → 이 변수 객체는 스코프가 참조하는 대상이 된다.

    (실행 컨텍스트 : 코드가 실행되기 위해 필요한 환경)

    (스코프 : 변수가 값을 참조할 때 접근할 범위)


2. 초기화 단계(Initialization phase)

    → 값을 저장하기 위한 메모리 공간을 확보하는 단계

    → 메모리가 만들어지면 undefined를 할당함


3. 할당 단계(Assignment phase)
    → undefined 로 초기화 된 변수에 실제 값을 할당하는 단계

 

 

 

var 의 호이스팅과 let, const 의 호이스팅이 다른 결과를 보여준이유는

아래와 같이 var, let, const 각각의 변수의 3단계 생성 과정 때문임.


var
1. 선언 + 초기화 → 그래서 값을 할당하기 전에 호출해도 error 를 내지않고, undefined를 보여줌
2. 할당

let
1. 선언(호이스팅 되면서 선언단계에 이루어짐)
2. 초기화(초기화는 실제 코드에 도달했을 때 이루어짐) → 그래서 ReferencEerror가 나타남
3. 할당

const
1. 선언 + 초기화 + 할당

 

 

 

 

변수의 유효 범위

유효 범위(scope): 변수에 접근 할 수 있는 범위

자바스크립트의 변수는 그 변수의 유효 범위에 따라 전역 변수지역 변수로 나뉨

- 전역 변수: 함수 바깥에서 선언된 변수. 유효 범위가 전체 프로그램임.

- 지역 변수: 함수 내부에 선언된 변수

let a = "global";
function 함수이름뭐로하지(){
    let b = "local";
    console.log(a); // global
    return b;
};

함수이름뭐로하지();
console.log(b); // ReferenceError: b is not defined

a는 전역 변수로, 유효 범위가 전체 프로그램이기 때문에

함수의 외부, 내부에서도 사용가능함.

 

b는 지역 변수로, 해당 함수 내부에서만 유효함.

그래서 바깥에서 console 찍으니까 정의되어있지 않다고 에러뜸.

 

 

 

 

변수의 충돌

변수에 유효범위가 있는 이유는

프로그램의 다른 부분에서 선언된 이름이 같은 변수와 충돌하지 않도록 하기 위함임.

다른 함수 내부에서 선언된 각각의 지역 변수는 해당 함수 내부에서만 유효함.

그래서 이름이 똑같아도 충돌 안함.

→ 함수 안에서 변수 이름 지을 땐, 다른 함수 안에서 사용하는 변수 이름까지 신경 안써도 됨.

 

하지만 전역 변수 이름이랑 지역 변수 이름이 같으면 두 변수가 충돌함.

이때는 함수 안에선 지역 변수가 사용되고, 전역 변수는 숨겨짐(함수 밖으로 나가면 전역 변수가 사용됨)

let a = "outer a";
function 함수이름뭐로하지(){
    let a = "inner a";
    console.log("함수 내부: " + a);  // 함수 내부: inner a
    return a;
};

함수이름뭐로하지();
console.log("함수 외부: " + a);  // 함수 외부: outer a

 

 

 

 

 

 

변수의 특징 표로 확인하기

  재선언 재할당 스코프
var 함수
let X 블록
const X X 블록

 

 

 

 

* var 는 선언과 초기화 단계가 동시에 이루어짐. 그래서 Error가 뜨지 않고 undefined를 출력하는 거임.
* let, const 는 선언, 초기화, 할당 단계가 각각 따로 이루어짐. 그래서 var 로 변수를 선언한 결과와 다르게 참조 에러가 나온다.

* function (함수 선언문) 은 선언, 초기화, 할당 단계가 동시에 이루어짐.

 

 

 

 




 

 

이 글을 쓰면서 참고한 사이트와 유튜브 입니다.

틀린 부분이 있다면 댓글로 알려주시면 감사하겠습니다.

• 여기저기 구글링...
• 드림코딩(https://www.youtube.com/watch?v=OCCpGh4ujb8&t=516s)
• 코딩앙마(https://www.youtube.com/watch?v=ocGc-AmWSnQ&t=138s)
• 코딩알려주는누나(https://www.youtube.com/watch?v=fETYLCU2YYc&t=16s)
• 수코딩(https://www.youtube.com/watch?v=ifhnOyoMX3U)
모던자바스크립트입문

반응형