노션에 적어서 했던 이론들을 정리하여 올려봅니다 : >
함수 안에 있는 선언들을 모두 끌어올려서 해당 함수 유효 범위의 최상단에 선언하는 것
자바스크립트 함수는 실행되기 전에 함수 안에 필요한 변수값들을 모두 모아서 유효 범위의 최상단에 선언한다
즉, 함수 내에서 아래쪽에 존재하는 내용 중 필요한 값들을 끌어올리는 것
실제 메모리에서는 변화가 없다
var 변수 선언과 함수선언문에서만 호이스팅이 일어남
~> var 변수/함수의 선언만 위로 끌어 올려지며, 할당은 끌어 올려지지 않는다.
let/const 변수 선언과 함수표현식에서는 호이스팅이 발생하지 않는다.
호이스팅은 함수선언문과 함수표현식에서 서로 다르게 동작하기 때문에 주의해야 한다.
~> 변수에 할당된 함수표현식은 끌어 올려지지 않기 때문에 이때는 변수의 스코프 규칙을 그대로 따른다.
function foo() { // 함수선언문
console.log("hello");
}
const foo2 = function() { // 함수표현식
console.log("hello2");
}
함수선언문은 코드를 구현한 위치와 관계없이 브라우저가 자바스크립트를 해석할 때 맨 위로 끌어 올려진다
즉, 해당 예제에서는 함수선언문이 아래에 있어도 printName 함수 내에서 inner를 function으로 인식하기 때문에 오류가 발생하지 않는다.
function printName(firstname) { // 함수선언문
var result = inner(); // "선언 및 할당"
console.log(typeof inner); // > "function"
console.log("name is " + result); // > "name is inner value"
function inner() { // 함수선언문
return "inner value";
}
}
printName(); // 함수 호출
/** --- JS Parser 내부의 호이스팅(Hoisting)의 결과 --- **/
function printName(firstname) {
var result; // [Hoisting] var 변수 "선언"
function inner() { // [Hoisting] 함수선언문
return "inner value";
}
result = inner(); // "할당"
console.log(typeof inner); // > "function"
console.log("name is " + result); // > "name is inner value"
}
printName();
함수표현식은 함수선언문과 달리 선언과 호출 순서에 따라서 정상적으로 함수가 실행되지 않을 수 있다.
함수표현식에서는 선언과 할당의 분리가 발생한다.
1) 함수표현식의 선언이 호출보다 위에 있는 경우 | 2) 아래에 있는 경우 (var) | 3) 아래에 있는 경우 (let,const)
function printName(firstname) { // 함수선언문
var inner = function() { // 함수표현식
return "inner value";
}
var result = inner(); // 함수 "호출"
console.log("name is " + result);
}
printName(); // > "name is inner value"
/** --- JS Parser 내부의 호이스팅(Hoisting)의 결과 --- **/
function printName(firstname) {
var inner; // [Hoisting] 함수표현식의 변수값 "선언"
var result; // [Hoisting] var 변수값 "선언"
inner = function() { // 함수표현식 "할당"
return "inner value";
}
result = inner(); // 함수 "호출"
console.log("name is " + result);
}
printName(); // > "name is inner value"
function printName(firstname) { // 함수선언문
console.log(inner); // > "undefined": 선언은 되어 있지만 값이 할당되어있지 않은 경우
var result = inner(); // ERROR!!
console.log("name is " + result);
var inner = function() { // 함수표현식
return "inner value";
}
}
printName(); // > TypeError: inner is not a function
/** --- JS Parser 내부의 호이스팅(Hoisting)의 결과 --- **/
function printName(firstname) {
var inner; // [Hoisting] 함수표현식의 변수값 "선언"
console.log(inner); // > "undefined"
var result = inner(); // ERROR!!
console.log("name is " + result);
inner = function() {
return "inner value";
}
}
printName(); // > TypeError: inner is not a function
Q. printName에서 “inner is not defined” 이라고 오류가 나오지 않고, “inner is not a function”이라는 TypeError가 나오는 이유?
A. printName이 실행되는 순간 (Hoisting에 의해) inner는 ‘undefined’으로 지정되기 때문
inner가 undefined라는 것은 즉, 아직은 함수로 인식이 되지 않고 있다는 것을 의미한다.
function printName(firstname) { // 함수선언문
console.log(inner); // ERROR!!
let result = inner();
console.log("name is " + result);
let inner = function() { // 함수표현식
return "inner value";
}
}
printName(); // > ReferenceError: inner is not defined
var myName = "hi";
function myName() {
console.log("yuddomack");
}
function yourName() {
console.log("everyone");
}
var yourName = "bye";
console.log(typeof myName);
console.log(typeof yourName);
/** --- JS Parser 내부의 호이스팅(Hoisting)의 결과 --- */
// 1. [Hoisting] 변수값 선언
var myName;
var yourName;
// 2. [Hoisting] 함수선언문
function myName() {
console.log("yuddomack");
}
function yourName() {
console.log("everyone");
}
// 3. 변수값 할당
myName = "hi";
yourName = "bye";
console.log(typeof myName); // > "string"
console.log(typeof yourName); // > "string"
var myName = "Heee"; // 값 할당
var yourName; // 값 할당 X
function myName() { // 같은 이름의 함수 선언
console.log("myName Function");
}
function yourName() { // 같은 이름의 함수 선언
console.log("yourName Function");
}
console.log(typeof myName); // > "string"
console.log(typeof yourName); // > "function"