호이스팅에 대해서 알아보자(feat. 함수 선언문 & 함수 표현식) in Javascript
호이스팅이란
자바스크립트 함수는 실행되기 전에 함수 안에 필요한 변수값들을 모두 모아서 유효 범위의 최상단에 선언한다.
자바스크립트 Parser가 함수 실행 전 해당 함수를 한 번 훑는다.
함수 안에 존재하는 변수/함수선언에 대한 정보를 기억하고 있다가 실행시킨다.
유효 범위: 함수 블록 {} 안에서 유효
즉, 함수 내에서 아래쪽에 존재하는 내용 중 필요한 값들을 끌어올리는 것이다.
실제로 코드가 끌어올려지는 건 아니며, 자바스크립트 Parser 내부적으로 끌어올려서 처리하는 것이다.
실제 메모리에서는 변화가 없다.
// 호이스팅의 대상 var 변수 선언과 함수선언문( function test () {} ) 에서만 호이스팅이 일어난다. var 변수/함수의 선언만 위로 끌어 올려지며, 할당은 끌어 올려지지 않는다. let/const 변수 선언과 함수표현식에서는 호이스팅이 발생하지 않는다. https://gmlwjd9405.github.io/2019/04/22/javascript-hoisting.html
예제1
- 처음 코드작성
console.log("hello"); var myname = "HEEE"; // var 변수
- 결과
var myname; // [Hoisting] "선언" console.log("hello"); myname = "HEEE"; // "할당"
예제2
console.log(hoisting); //undefined
var hoisting = "success";
console.log(hoisting); // 'success'
호이스팅을 할 때 처음 자바스크립트에서
var hoisting; 으로 되었는데
선언만 끌어올리고 값은 안 올렸기 때문에
첫번째줄 console.log(hoisting)은 undefined가 나옴
객체가 선언되고 값이 세팅된 적이 없다면 undefined를 반환하고,
사용자가 값이 없다라고 null을 설정한 경우라면 null을 반환합니다.
var a = null;
var b;
위의 두 값을 출력해 보면 a 는 null, b 는 undefined 를 출력
// 함수 선언문
function a() { retrun 'a'
}
// 기명 함수표현식
var b = function bb() {
return 'bb'; }
- 변수 c선언
- 익명함수 선언
- 변수 c에 익명함수를 할당
요즘엔 브라우저에서는 함수명이 비어있을경우 자동으로 변수명에 할당하기 때문에
익명 함수표현식을 사용한다.
같은 기능의 함수가 호이스팅되어
원했던 결과가 안 나오는것을 방지하기 위해
function a () {
return 'a'
} 보다
var a = function () {
return 'a'
} 방식인 함수표현식을 쓰자
(by. 더글라스 크락포드)
TIP 호이스팅 사용 시 주의
코드의 가독성과 유지보수를 위해 호이스팅이 일어나지 않도록 한다.
호이스팅을 제대로 모르더라도 함수와 변수를 가급적 코드 상단부에서 선언하면,
호이스팅으로 인한 스코프 꼬임 현상은 방지할 수 있다. let/const를 사용한다. var를 쓰면 혼란스럽고 쓸모없는 코드가 생길 수 있다.
그럼 왜 var와 호이스팅을 이해해야 할까? ES6를 어디에서든 쓸 수 있으려면 아직 시간이 더 필요하므로 ES5로 트랜스컴파일을 해야한다. 따라서 아직은 var가 어떻게 동작하는지 이해하고 있어야 한다.
https://gmlwjd9405.github.io/2019/04/22/javascript-hoisting.html
https://gmlwjd9405.github.io/2019/04/20/function-declaration-vs-function-expression.html
함수표현식과 함수선언식 차이
함수표현식 (Function Expression)
- 변수값에 함수 표현을 담아 놓은 형태 유연한 자바스크립트 언어의 특징을 활용한 선언 방식
- 함수표현식은 익명 함수표현식과 기명 함수표현식으로 나눌 수 있다. 일반적으로 함수표현식이라고 부르면 앞에 익명이 생략된 형태라고 볼 수 있다. 익명 함수표현식: 함수에 식별자가 주어지지 않는다. 기명 함수표현식: 함수의 식별자가 존재한다.
- 함수표현식의 장점 클로져로 사용 콜백으로 사용(다른 함수의 인자로 넘길 수 있음)
var test1 = function() { // (익명) 함수표현식 return '익명 함수표현식'; }
var test2 = function test2() { // 기명 함수표현식 return '기명 함수표현식'; }
함수선언문은 호이스팅에 영향을 받지만, 함수표현식은 호이스팅에 영향을 받지 않는다.
- 함수선언문은 코드를 구현한 위치와 관계없이 자바스크립트의 특징인 호이스팅에 따라 브라우저가 자바스크립트를 해석할 때 맨 위로 끌어 올려진다.
- 함수표현식은 함수선언문과 달리 선언과 호출 순서에 따라서 정상적으로 함수가 실행되지 않을 수 있다.