[JS] 함수 선언문과 함수 표현식

소연·2024년 1월 18일

일러두기

본 글은 ‘모던 자바스크립트 Deep Dive’ 12장, ‘함수’를 참고하여 작성되었습니다.



함수를 정의하는 방식

함수 정의 방식예시
함수 선언문function add (a,b){ return a+b }
함수 표현식var add = function(a,b){ return a+b }
Function 생성자 함수var add = new Function(’a’, ‘b’, ‘return a + b’)
화살표 함수 (ES6)var add = (a, b) ⇒ a + b;

함수를 정의하는 방식에는 크게 네 가지가 있다. 나는 함수선언문은 주로 컴포넌트를 만들 때 사용했었고 그 외의 함수(예: Handler, 각종 utils 함수) 를 제작할 땐 화살표 함수를 사용했던 것 같다.

다소 생소한 함수 표현식,,

var add = function(a,b){ return a+b }

그런데 함수 표현식으로 함수를 정의하는 예시는 처음 봤다. 교재에서 함수 선언문으로 함수를 정의할 때와 함수 표현식으로 함수를 정의할 때를 두고 비교하는 내용이 있는데 인상 깊어서 이 내용을 위주로 정리 해봤다.


차이1. 문이냐 표현식이냐?

  • 함수 선언문으로 정의한 함수는 그 자체로 ‘문’이다.
  • 함수 표현식으로 정의한 함수는 평가된 값을 변수에 할당한다.

차이2. 호이스팅의 원리

// 함수 참조
console.dir(add); // ƒ add(x, y)
console.dir(sub); // undefined

// 함수 호출
console.log(add(2, 5)); // 7
console.log(sub(2, 5)); // TypeError: sub is not a function

// 함수 선언문
function add(x, y) {
  return x + y;
}

// 함수 표현식
var sub = function (x, y) {
  return x - y;
};

add라는 함수는 ‘함수 선언문’ 방식으로 정의되었고, sub이라는 함수는 ‘함수 표현식’방식으로 정의 되어있다.

그리고 이 함수들을 정의한 문보다 앞서서 각 함수들을 참조하고, 호출해봄으로써 각 방식으로 정의된 함수에서 어떻게 다른 호이스팅의 양상을 보이는지 확인해보고 있다.


함수 선언문: 함수 호이스팅

함수 선언문으로 정의된 함수는 런타임 이전에 자바스크립트 엔진에 의해 먼저 실행된다고 한다. 런타임 이전에 add라는 식별자에 함수객체를 가리키는 주소를 할당한다.
즉, 함수를 정의하는 곳보다 윗쪽에서 함수를 참조하거나 호출해도 참조에러나 타입에러가 발생하지 않는 ‘함수 호이스팅’이 일어나는 것이다.


함수 표현식: 변수 호이스팅

변수 선언 var sub 부분 역시 런타임 이전에 자바스크립트 엔진에 의해 먼저 선언되고, var 키워드로 선언된 변수일 경우 undefined로 초기화까지 완료된다. 하지만 sub이라는 변수에 함수 표현식이 평가되어 ‘함수객체’ 라는 값으로 할당이 되는 것은 런타임의 일이다. 따라서 함수 표현식으로 정의한 함수의 경우 참조했을 때 참조 에러가 아닌 undefined라는 값을 참조할 수 있다. 함수표현식으로 정의한 함수의 호이스팅은 변수의 호이스팅과 같은 원리로 일어난다.

undefined라는 값이 할당되었고, undefined는 호출할 수 있는 값이 아니므로 함수를 상단에서 ‘호출’하려고 할 땐 TypeError가 발생한다.

0개의 댓글