본문 바로가기
Frontend

[JS] 호이스팅 : Hoisting

by dug_developer 2022. 6. 8.
반응형

var, let, const 전부다 호이스팅은 되지만 let과 const는 호이스팅이 안되는 것처럼 동작한다.

호이스팅 요약

변수를 선언하고 할당했을 때 선언부분이 최상단으로 끌어올려지는 현상

⭐ 많이 헷갈리는 부분이 선언과 동시에 초기화해도
선언부분만 분리하여 최상위로 끌어올린다.
ex)
let a = 10;일때
let a;만 최상위로 올라감

 

👍🏻 출석체크 먼저 할게~
역할(값 할당)은 이따가 정해줄게~!

 

즉, JS엔진은 선언문이 어디에 위치하든 다른코드보다 먼저 실행한다.

따라서, 변수선언이 어디에 위치하든지 상관없이 어디서든 변수를 참조할수있다.

 

메모리 공간을 먼저 확보한다는 것이다!

 

변수 생성 3단계

  1. 선언 단계 : 변수를 실행컨텍스트의 변수 객체에 등록함
  2. 초기화 단계 : 실행 컨텍스트에 등록된 변수객체에 대한 메모리를 할당한다.
    • 이 단계에서 변수들은 undefined로 초기화된다.
  3. 할당 단계 : undefined로 초기화된 변수에 값을 할당한다.
console.log(score); // undified

var score; // 변수 선언
score = 80; // 값 할당

console.log(score) // 80
👍🏻 JS엔진은 변수 선언시 일단 undefined를 할당해준다.

  • const 는 바로 할당해줘야해서 이건 적용안됨
  • let에 아무것도 안담으면 undefined가 담기는 것을 생각해라.

 

  • 그래서 값을 할당하는 부분을 만나면 재할당하는 것이 된다.
  • 그리고 이전값인 undefined가 메모리공간에서 지워지고 그자리에 80이 저장되는 것이 아니라 새로운 메모리공간을 확보하고 그곳에 80을 저장하는 것이다.그리고 또 값을 90으로 변경하면 또 다른 새로운 메모리 공간에 값을 저장한다.
    • 그전의 값들인 undefined나 80은 아무도 사용하고 있지 않는것이다.

새로운 메모리에 할당된 모습

var의 경우

  • 선언단계와 초기화 단계가 같이 이뤄져서 undefined로 초기화가된다.
console.log(name) // undefined
var name = ‘seo’

var는 사용하지마!

var는 호이스팅이 일어나기 때문에 사용하지 말라는 것이다

  • 값을 선언하기 전에 사용할 수 있는 것!
    • 예상치 못한 버그를 일으킬수 있다.
  • 블럭을 무시함, 즉 지역을 무시한다.
  • var변수와 함수는 자동으로 호이스팅이 된다
  • var 는 undefined으로 초기화된다.
    • 해당 변수 선언부분 전에서 호출시 undefined가 출력된다.
    • 할당 부분을 만나면 그때 지정한 값이 할당된다.

let과 const

  • let또는 const키워드로 선언된 변수는 초기화되지 않은 상태(uninitialized)로 저장됩니다 .
    • 해당 변수 선언부분 전에서 호출시 에러가 난다.

let, const의 호이스팅

  • 선언과 초기화단계가 분리되어 진행된다.
    • 일단 JS엔진에서 선언만 해놓음
  • 호이스팅이 안되는 것처럼 동작한다.
  • 초기화단계는 변수 선언문에 도달했을 때 실행된다.
let age;
console.log(age); //undefined
age = 20;
console.log(age); //20
  • 초기화단계가 실행되기 이전에 변수에 접근하려고 하면 참조에러가 발생한다.
    • 이 구간을 TDZ 존이라고 한다.
    • 즉, 엔진에서는 그블록에서 이미 변수가 있다는 건 알고 있지만 접근하려고하면 에러를 띄운다.
console.log(name) // ReferenceError: name is not defined let name = ‘seo’

let의 경우 일단 undefined가 할당은 됨

  • 선언단계와 초기화 단계가 분리되어 진행된다.
  • let키워드로 선언된 변수는 hoisting되어 선언단계가 이뤄지고 초기화 단계는 실제 let이 사용된 코드에 도착했을 때 이뤄진다.
  • 그래서 아직 초기화가 안됬는데 접근 하려고 해서 에러가 난다.

const의 경우

  • const 변수는 let과 매우 유사하지만 차이점은 const 로 선언되면 값이 상수화되어 변경이 불가능합니다.
  • const 로 선언될 경우 선언과 동시에 초기화를 해야 합니다.

TDZ (Temporal Dead Zone)

실제 선언 이전의 "영역"을 시간적 데드존 TDZ(Temporal Dead Zone) 이라고 한다

그때 호출을 하려고 하면 ReferenceError가 나온다.

  • ⭐엔진이 실제로 변수를 선언한 부분을 통과하면 메모리의 값을 실제로 선언한 값으로 덮어씀
  • let / const선언과 동시에 TDZ에 들어가서 초기화가 필요한 별도의 상태로 관리된다.
  • const 는 선언과 동시에 초기화, 할당까지 이루어진다.

즉 그 선언된 코드를 만나고부터 변수를 참조할 수 있다.

  • 스코프 안에서는 선언되어있다는 걸 알지만 코드를 만나기 전까진 참조할 수없다.
1. JS엔진이 일단 변수들을 다 출석체크 함
2. "역할은 직접 만나서 줄게!" 
	해당 라인을 만나야지 그때부터 사용할 수 있다.

그렇다면 let과 const 는 호이스팅이 안되는 것인가?

let/const선언 변수도 호이스팅이 된다.

  • 스코프에 진입할 때 변수가 만들어지고 TDZ(Temporal Dead Zone)가 생성되지만, 코드 실행이 변수가 실제 있는 위치에 도달할 때까지 액세스할 수 없는 것이다.
  • let/const변수가 선언된 시점에서 제어흐름은 TDZ를 떠난 상태가 되며, 변수를 사용할 수 있게 된다.

즉, 접근만 못하게 막은 것이지 호이스팅은 되고 할당부분을 만나면 변수를 참조할 수 있게 된다.

TIP 호이스팅 사용 시 주의

  1. 코드의 가독성과 유지보수를 위해 애초에 호이스팅이 일어나지 않도록 한다.
  2. 호이스팅을 제대로 모르더라도 함수와 변수를 가급적 코드 상단부에서 선언하면, 호이스팅으로 인한 스코프 꼬임 현상은 방지할 수 있다.
  3. let/const를 사용한다.
    • var를 쓰면 혼란스럽고 쓸모없는 코드가 생길 수 있다.
반응형

'Frontend' 카테고리의 다른 글

CORS 와 SOP  (0) 2022.06.17
브라우저의 동작 원리 (렌더링 과정)  (0) 2022.06.17
개발자 단계  (0) 2022.05.08
redux 총정리  (0) 2022.04.29
jsconfig.json : 경로 설정  (0) 2022.04.29