호이스팅 📖
호이스팅이란? 사전에 검색해 보면 `끌어올리기`, `들어 올려 나르기`라고 나옵니다!
단어 뜻처럼 스크립트 내에 변수나 함수의 선언이 스코프 최상단으로 끌어올려지는 현상을 말합니다.
❗여기서 포인트는 물리적으로 끌어 올려지는 것이 아니라 코드 전체를 스캔하고 실행 컨텍스트에 미리 기록하기 때문에 이런 현상이 발생합니다!
실행 컨텍스트가 궁금하시면❓
예시코드 (매개변수, 변수)✅
매개변수 및 변수는 선언부를 호이스팅 합니다.
function a () {
var x = 1;
console.log(x);
var x;
console.log(x);
var x = 2;
console.log(x);
}
a(1);
위 예시 코드의 실행 결과를 한 번 예상해 보세요~!
아마도 `1 -> undefined -> 2` 순으로 출력이 될 거라고 많이 예상들 하셨겠지만 ❌
예시코드(호이스팅 적용) ✅
function a () {
var x;
var x;
var x;
x = 1;
console.log(x);
console.log(x);
x = 2;
console.log(x);
}
a(1);
실제론 `1 -> 1 -> 2`가 출력이 됩니다.🧐
예시코드 (함수)✅
함수 선언은 전체를 호이스팅 합니다.*함수라고 해서 무조건 다 호이스팅 되는 건 아닙니다! 아래에서 설명해 드릴게요~
//action point 1 : 결과 값 예상해보기
//action point 2 : hoisting 적용해본 후 결과를 다시 예상해보기
function a () {
console.log(b);
var b = 'bbb';
console.log(b);
function b() { }
console.log(b);
}
a();
위 예시 코드의 실행 결과를 한 번 예상해 보세요~!
`오류 -> bbb -> function` 순으로 출력될 것이라 예상하시겠지만 ❌
예시코드(호이스팅 적용) ✅
function a () {
var b; // 변수 선언부 호이스팅
function b() { } // 함수 선언은 전체를 호이스팅
console.log(b);
b = 'bbb'; // 변수의 할당부는 원래 자리에
console.log(b);
console.log(b);
}
a();
실제론 `function -> bbb -> bbb`가 출력이 됩니다.🧐
호이스팅을 예상하기 전이랑 결과가 다르게 나옵니다. 이처럼 호이스팅을 고려하지 않고 결과를 예측하기 매우 어렵다는 것입니다.
함수의 호이스팅 📖
예시코드 ✅
`함수 선언문` : 함수 정의부만 존재하고 할당 명령이 없는 경우
`함수 표현식` : 함수를 별도 변수에 할당하는 경우
console.log(sum(1, 2));
console.log(multiply(3, 4));
function sum (a, b) { // 함수 선언문 sum
return a + b;
}
var multiply = function (a, b) { // 함수 표현식 multiply
return a + b;
}
`함수 선언문` 같은 경우에는 전체가 위로 쭉 끌어올려지지만 `함수 표현식` 같은 경우에는 변수에 할당하기 때문에 선언부만 호이스팅 되는 걸 볼 수 있습니다.
// 함수 선언문은 전체를 hoisting
function sum (a, b) { // 함수 선언문 sum
return a + b;
}
// 변수는 선언부만 hoisting
var multiply;
console.log(sum(1, 2));
console.log(multiply(3, 4));
multiply = function (a, b) { // 변수의 할당부는 원래 자리
return a + b;
};
협업을 많이 하고, 복잡한 코드일수록 `함수 표현식`을 활용하는 습관을 가지는 게 좋습니다!
var, let, const 차이점 📖
var, let, const
`var` 키워드는 재선언, 재할당이 가능합니다.
var greeter = "hey hi";
var greeter = "say Hello instead";
var greeter = "hey hi";
greeter = "say Hello instead";
`let` 키워드는 재선언은 불가능하지만 재할당은 가능합니다.
let greeting = "say Hi";
let greeting = "say Hello instead"; // error: Identifier 'greeting' has already been declared
let greeting = "say Hi";
greeting = "say Hello instead";
`const` 키워드는 재선언, 재할당 모두 불가능합니다.
const greeting = "say Hi";
greeting = "say Hello instead";// error: Assignment to constant variable.
const greeting = "say Hi";
const greeting = "say Hello instead";// error: Identifier 'greeting' has already been declared
변수 호이스팅 방식
변수는 `선언` -> `초기화` -> `할당`에 걸쳐 생성되는데
`var` 키워드로 선언한 변수는 `선언`, `초기화`가 동시에 이뤄집니다.
console.log(name); // undefined
var name = "Anna";
console.log(name); //Anna
하지만 할당은 되지 않았기 때문에 첫 번째 줄에 console.log(name)은 `선언`과`초기화`가 된 var name;을 출력하기 때문에`undefined`를 출력하게 됩니다.
`let` `const`키워드로 선언한 변수는 `선언`과`초기화`가 분리되어 진행됩니다.
코드 실행 전에는 변수 선언만 해두며 초기화는 변수 선언문을 만났을 때 수행합니다.
console.log(a); // ReferenceError :: 변수 선언 이전에 변수 참조 불가능
let a // 초기화
console.log(a); // undefined
a = 10 // 할당
consloe.log(a); // 10
그리고 `var` 키워드와는 다르게 선언된 변수를 앞에서 참조하려고 할 때 `ReferenceError`가 발생합니다.
하지만 오류가 발생해서 호이스팅이 발생하지 않는 것처럼 보이지만 접근만 하지 못하게 된 것입니다. 여기서 `TDZ(Temporal Dead Zone)`에 대한 개념이 나옵니다.
TDZ(Temporal Dead Zone)
`TDZ`를 한글로 하면 일시적인 사각지대란 뜻입니다.
let과 const을 사용할 때 변수 선언 및 초기화하기 전 값에 접근하게 되면 되면 ReferenceError가 발생하게 됩니다.
'공부 > javascript' 카테고리의 다른 글
javascript 심화 6 (이벤트 루프) (0) | 2024.08.02 |
---|---|
javascript 심화 5 (Promise, async, await) (0) | 2024.07.29 |
javascript 심화 4 (콜백함수) (0) | 2024.07.29 |
javascript 심화 3 (this, 화살표함수, call, apply, bind) (0) | 2024.07.26 |
javascript 심화 1 (실행 컨텍스트) (0) | 2024.07.24 |
javascript 기본 4 (불변 객체, 얕은 복사, 깊은 복사) (0) | 2024.07.23 |
javascript 기본 3 (기본형, 참조형 데이터와 불변성) (1) | 2024.07.23 |
Javascript 기본 2 (조건문, 반복문, 배열, 객체) (2) | 2024.07.22 |