본문 바로가기
FE/JavaScript

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

by thedev 2022. 10. 23.

 

함수 선언문과 함수 표현식

 


함수는 두 가지 방식으로 정의할 수 있다.

 

 

1. 함수 선언문

 

function add(x, y){
   return x + y;
}

 

 

2. 함수 표현식

 

const add = function(x, y){
   return x + y;
}

 

ES6의 화살표 함수도 이에 해당한다.

 

const minus = (x, y) => {
   return x - y;
}

 

 함수 선언문과 함수 표현식의 차이는 무엇일까? 함수 생성 시점이 다르다. 함수 선언문은 런타임 이전에 먼저 실행되어 함수 객체로 초기화되어 함수 선언문 이전에 함수를 참조할 수 있다. 즉, 함수 호이스팅이 발생한다.

 

 하지만 const로 실행된 함수 표현식은 함수 호이스팅이 아닌 변수 호이스팅이 발생한다. 따라서 undefined 값으로 초기화되고, 런타임 시점에서 함수 객체가 된다.

 

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

// 함수 호출
console.log(plus(1, 2)); // 3
console.log(minus(1, 2)); // Uncaught TypeError: minus is not a function

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

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

 

 

 함수 선언문으로 정의된 함수는 선언 이전에 호출할 수 있고, 초기값으로 함수 객체가 할당된다. 그러나, 함수 표현식으로 정의된 함수는 변수 호이스팅이 발생하기 때문에 초기값으로 undefined가 할당된다.

 

 함수 선언문으로 정의된 함수는 이미 초기값으로 함수 객체를 갖고 있으므로, 선언하기 이전에 plus(1, 2)처럼 값을 넣어도 실행이 된다. 그러나 함수 표현식으로 정의된 함수의 초기값은 함수 객체가 아닌 undefined이라 타입 에러가 발생한다. 함수 표현식의 값은 실행되는 시점에 지정되기 때문이다.

 

 즉, 함수 선언문은 선언 이전에 사용할 수 있고, 함수 표현식은 선언 이후에 사용할 수 있다. 그러나 함수 표현식으로 정의된 함수는 다른 함수의 인자, 즉 콜백 함수로 이용할 수 있다는 장점이 있다.

 


+ 별 건 아니지만 궁금한 거 메모...

 

console.dir(plus); // ƒ plus(x, y)
console.dir(minus); // Uncaught ReferenceError: minus is not defined

console.log(plus(1, 2));
console.log(minus(1, 2));

function plus(x, y) {
  return x + y;
}
const minus = function (x, y) {
  return x - y;
};

 

console.dir(plus); // ƒ plus(x, y)
console.dir(minus); // Uncaught ReferenceError: minus is not defined

console.log(plus(1, 2));
console.log(minus(1, 2));

function plus(x, y) {
  return x + y;
}
let minus = function (x, y) {
  return x - y;
};

 

 함수 표현식을 var이 아니라 const나 let으로 선언하면 타입 에러가 아니라 참조 에러가 뜬다. var, const, let의 구체적인 차이를 더 알아봐야겠다.🤔

 

 

참고 자료 : 모던 자바스크립트 Deep Dive 12장