오늘은 호이스팅에 대해서 알아보자
근데 사실 나도 이번에 공부하면서 처음 들어봄
단어 뜻을 검색해보니까
..? "감아 올리기" 라고 한다
hoist[hɔɪst] : (흔히 밧줄이나 장비를 이용하여) 들어[끌어]올리다
(3인칭 단수 현재 : hoists)
동사
진짜넹
그러면 자바스크립트에서
호이스팅은 무엇이고,
도대체 무엇을 끌어올리는걸까?
"변수의 선언과 초기화를 분리한 후, 선언만 코드의 최상단으로 옮기는 것"
그러니까, 바로 "선언"을 끌어올리는거임.
자바스크립트에서 변수를 선언하는 방법은 세 가지가 있음
변수 재선언이 가능한 var는 변수를 보호하지 못하고,
중복 선언이 가능해서 문제가 많음 (쓰면 혼남)
var
로 선언한 변수는 호이스팅 시undefined
로 변수를 초기화함
근데let
이랑const
로 선언하면 호이스팅 할 때 변수 초기화 안함
var a = "힘들게 계산한 값 ㅠㅠ";
console.log(a) //"힘들게 계산한 값 ㅠㅠ"
...
...
var a = "ㅋㅋ어쩔티비";
console.log(a) //"ㅋㅋ 어쩔티비"
이렇게 선언해놓은 변수명을 다시 쓸 수 있음
그럼 let이랑 const는 뭐가 다르죠
이건 let
let a = 5; let a = 6; console.log(a) // 변수 "재선언" 불가능! SyntaxError: Identifier 'a' has already been declared a = 6; console.log(a) // 이건 가능. 값만 "재할당"
이건 const
const b = 5; const b = 6; console.log(b) // 변수 "재선언" 불가능! SyntaxError: Identifier 'a' has already been declared b = 6; console.log(b) // 값 재할당도 불가능함. TypeError: Assignment to constant variable
let과 const 둘 다
변수 재선언이 불가능 (기존에 쓰이던 var의 문제점)
다만, let에 한해서 값 재할당이 가능하다.
그래서 사실 const로 선언한건 변수가 아니라 상수가 맞을듯
( 상수가 영어로 constant임 )
변수 선언 방식의 차이에 대해서 알아보았으니
이제 어떻게 선언을 호이스팅 하는지,
도대체 호이스팅이 무엇인지 알아보자
자바스크립트는 ES6에서 도입된 let, const를 포함한
모든 선언(var, let, const, function, class)을 호이스팅함
호이스팅은 변수 및 함수의 메모리 공간을 선언 전에 미리 할당하는 것
초기화를 제외한 선언만 호이스팅함
그래서 선언, 정의된 다른 코드보다 호출하는 코드를 먼저 작성할 수 있음
console.log(myName) //호이스팅한 var 선언으로 인해 undefined 출력
var myName; //선언
myName = "Sungho" //초기화
엥 변수 선언도 안했는데 호출부터 하면 어떡해여
자바스크립트 엔진은 컴파일 과정에서 미리 변수들을 스캔해서
실행 컨텍스트에 변수 객체를 저장함
즉, 미리 선언된 변수들을 수집하여 마치
스코프 상단에 변수가 "끌어올려진" 것 같은 느낌이 된거임
??: "undifined 뜨는뎁쇼"
변수 생성은 세 단계를 거침
1. 선언
2. 초기화
3. 할당
- "선언"되면 변수가 실행 컨텍스트의 변수 객체에 등록된다
- "초기화"는 등록된 변수를 위한 공간을 메모리에 마련하는 undefined 상태
- "할당"은 undifined로 "초기화"된 변수에 실제 값을 할당함 (undefined값 -> 특정 값)
var는 선언과 동시에 초기화가 이루어지는데,
let은 선언될 때 초기화 안되고
TDZ(TDZ가 뭥미)에 갇히는 상태임
그래서 var의 호이스팅 결과는 undefined가,
let과 cosnt는 에러 뜸
myName("김성호")
function myName(name) {
console.log("안녕 내 이름은 " + name + "입니다.")
}
??: "엥 함수 선언도 안하고 호출부터 하면 어떡합니까"
잘 돌아감
근데
myName("김성호") const myName = (name) => { console.log("안녕 내 이름은 " + name + "입니다.") }
이거는 안됨
왜 그러냐면
"함수"의 선언과
"변수"의 선언이 규칙이 서로 달라서 그렇다.
(익명함수는 함수를 선언한게 아니라 "변수"에 담아서 표현한거니까)