JavaScript Hoisting

wonkeunC·2021년 11월 17일
0

JavaScript

목록 보기
10/15
post-thumbnail

JavaScript Hoisting(호이스팅)

Hoisting의 사전적 의미 : 무언가를 들어올리다 / 끌어올리다
Hoisting의 자바스크립트 의미 : 변수를 끌어올린다는 뜻

실행 컨텍스트가 활성화 되었을때 해당 영역에서 변수의 이름을 메모리에 먼저 수집하는 현상으로 인해 발생하는 현상.
즉, 유효범위의 코드가 실행되기 전 메모리에 먼저 저장했던 선언문을 사용할 수 있다.

🔎 왜 Hoisting을 설명하는가?

이유는 변수 var과 let의 차이점에 대해 얘기하기 위해서 Hoisting을 언급하게 되었다.
우리가 흔히 변수를 선언할 때 var과 let을 사용한다. 하지만 let이 존재하지 않았던 ES6 문법 이전에는 var 밖에 없었다.
그렇기 때문에 변수를 사용하기 위해 var만 남용해야 했던 것이다. 이렇게 var에 대한 문제점이 하나둘씩 나타나게 되었고 var의 문제점을 개선하기 위해 2015년에 나온 ES6 문법 중에 변수 let이 등장하게 되었다.


📝 호이스팅 시 발생되는 var의 문제점 1️⃣

우선 JavaScript의 특징을 살펴보자!
JavaScript는 코드를 위에서 아래서 흝기 전에 🤖 JavaScript 엔진으로 코드 안에 선언해둔 변수,함수가 어떤 것들이 있는지 파악하고 메모리에 저장해둔다. ( 미리 조사를 함 )

var gender = "male"  <----
var job = "백수"        <----   🤖 JavaScript 엔진        
var name = "뀨"        <----    이런 녀석들이 있군 
var age = 26           <----   선언된 변수와 함수를 가져가서 메모리에 기억해둔다. 
                                  |
function eventHandler() {  <------|
  code...
}

  useEffect(() => {
    let complete = 0;
    const timer = setInterval(() => {
      if (complete >= 100) {
  code...
  }, [isLoad]);

👨‍💻 사용자 (나) : 아까 변수 name을 선언해 뒀으니까 이 코드안에서 name을 사용해야겠다 !
🤖 JavaScript 엔진 : 너가 선언한 var name = "뀨" 를 나의 메모리 안에 저장해뒀지! 너에게 주마 !

이것이 Hositing 개념! 즉, 함수가 실행되기 전에 안에있는 변수들을 최 상단으로 끌어올리는 것.

조금 더 살펴볼까..
🚨 알아두기 : 코드는 Run 즉, 실행되면 항상 Top to Bottom 위에서 아래로 흘러간다.

"첫번째 예시"

1 | var box = 10;
2 | console.log(box)

결과
10

"두번째 예시"

☘️
1 | console.log(box)  <-- box를 생성하기 전에 console을 찍으면 일반적으로 이 코드는 Error:"box를 찾을 수 없음" 가 난다.
2 | var box = 10;
3 | console.log(box) <--- 얘는 정상

결과 
undefined  <-- Error가 나지 않고 undefined를 출력한다.
10

"세번째 예시"

1 | console.log(box)  <-- 아무런 코드 없이 box만 콘솔을 찍었을때

결과
ReferenceError: box is not defined at script/...

"두번째 예시" 에서 
1 | console.log(box) 
는 error가 아닌 undefined를 출력할까? --> 바로 Hoisting 때문이다. 

👨‍💻 내가 코드를 Run 즉, 실행시키기 전에 🤖JavaScript 엔진이 나와서 코드를 확인한다.
			     
                                 👇
1 | console.log(box) 
2 | var box = 10;  <-- 🤖 JavaScript 엔진 : box가 선언되있네? var box  내가 저장해둘께 !
3 | console.log(box) 
4 |

그 다음부터 !
▶️ 코드 Run(실행)

1 |2 |3 |4 | 로 코드가 출력된다.

📝 정리 :
1 | console.log(box) <-- 가 error가 아닌 undefined를 출력한 이유는 코드가 ▶️실행되기 전에 
🤖 JavaScript 엔진이 var box = 10 <-- 의 코드 위치가 어디에 있든 그 변수를 메모리에 저장시키고 
그 이후에 코드가 실행되기 때문에 undefined를 출력하게 되는 것이다 ! 

JavaScript는 호이스팅 시 변수의 선언과 변수의 초기화(undefined으로)를 같이 시켜버린다.
변수가 선언되기 전 위치에 👨‍💻 사용자가 변수를 불러오게 되면 🤖JavaScript 엔진은 변수안에 undefined라는 값을 넣어버린다. 제대로 된 값 할당은 나중에 변수가 선언된 줄에서 엔진이 제대로 된 값을 보내준다.


📝 호이스팅 시 발생되는 var의 문제점 2️⃣

🚨 var은 전역변수와 지역변수의 개념이 확실치 않다.

1 | console.log(box);
2 | box = 10; <-- var 로 변수 선언도 안해줬다!
3 | var box;  <-- 선언을 할당 뒤에서 해줬다.
4 | console.log(box)

결과
undefined
10

전역변수: 블락 밖에서 선언을 한 어디서든 쓰일 수 있는 변수.
지역변수: 블락 {} 안에서 선언된 변수, 블락안에서만 사용 가능하다.

// 전역변수
var a = 10;
var loading = true;

function handleClock(){
  var clockTime = 12; // 지역변수
}

console.log(clockTime); <-- ReferenceError: clockTime is not defined
//clockTime은 함수 안에서 선언된 변수이기 때문에 밖에서는 사용될 수 없다.

for(var i = 1; i < 5; i++) {
  console.log(i);
}
console.log(i) "<-- i는 for문 안에 선언된 변수라 에러가 나야 정상이다." 

결과
1 
2   
3  
4 
5 "<-- for문 밖 console.log(i) 출력 값"

⭐️ 중요 !

var은 함수만 지역변수로 호이스팅(Hoisting)이 되고 나머지는 다 전역변수로 올려버린다.
함수(function)만 제외하고 for문, if문 안에 사용한 것들 모두 전역변수로!


"하나 더 봅시다"
변수의 이름은 절대 중복이 되서는 안된다 . 하지만! 자바스크립트는 이것마저 허용한다..

1 | var box = 1 
2 | console.log(box)
3 | var box = 2
4 | console.log(box)

결과
1
2

📝 var에 대한 결론 !

이러한 var의 다양한 문제점들 때문에 JavaScript를 만든 브렌던 아이크 님은 var의 문제점을 해결해 줄 친구들을 만들었다. 그 친구는 바로! let 이다!




💪 let 너의 힘을 보여줘!

"예시 1"

1 | let box = 1;
2 | console.log(box);
3 | let box = 2;
4 | console.log(box)

결과
👉 Identifier 'box' has already declared ..

"예시 2"

1 | for(let box = 1; 1 < 5; box++){
2 | console.log(box);
3 | }
4 | console.log(box);
  
결과
ReferenceError: box is not defined at script.js: 4 <-- 4번째 줄 console.log의 box는 error.
1
2
3
4

1 | console.log(box)
2 | let box = 10;
3 | console.log(box);

결과
ReferenceError: cannot access 'box' before initialization at script.js: 1

🔎 let에 대해 알아보기

  • let도 호이스팅(Hoisting)이 가능하다.
  • let에는 TDZ(Temporal Death Zone)이라는 개념이 있다.

코드로 살펴보자 !

1 | console.log(a); <-- "a가 호이스팅으로 기억이 된건 알겠어 하지만", "일시적으로 너는 죽은(TDZ) zone이야"
2 | let a = 10;  <-- "a의 선언문이 나오기 전 까지는 너는 a에 접근할 수 없다. "
3 | console.log(a);

"그렇기 때문에 나온" 결과 "는"
결과 
ReferenceError: cannot access 'box' before initialization at script.js: 1

👆설명 : 
1 | console.log(a), 너는 "첫번째 줄" TDZ이기 때문에 a에 접근할 수 없어 a가 초기화 되는 줄은 
2 | let a = 10, "두번째 줄" 이거든

a 에 대한 초기화문이 나올때 까지는 그 앞에서 어떤 식으로 a를 쓰려고 하던지 a가 선언된 라인 전까지는 (TDZ)일시적 사각지대 이기 때문에 a를 사용할 수 없다.


👋 결론

let이 나온 것은 그렇게 오래되지 않았기 때문에 오래전에 작성한 코드에서 var이 많이 사용되는 것을 볼 수 있다. 하지만 var에 대한 문제점들이 많기 때문에 let이 나왔고 JavaScript에서 let을 지향하라고 얘기도 많이 하였다.
var은 위험요소가 많기 때문에 사용을 지양하라(되도록이면 쓰지 말아라!)
let을 지향하라!

profile
개발자로 일어서는 일기

0개의 댓글