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

Yeon Jeffrey Seo·2022년 1월 11일
0

JavaScript

목록 보기
4/7
post-custom-banner

함수 선언문(Function Declaration)

함수 선언문은 function 키워드를 사용해서 함수를 정의한다

function foo() {
  return "Hello World!"; 
}

console.log(foo()); // Hello World!

함수 표현식(Function Expression)

함수 표현식은 함수를 생성하고, 변수에 그 함수를 할당하여 정의하는 방법이다.

let foo2 = function () {
  return "Fooooo"; 
}

console.log(foo2()); // Fooooo

자바스크립트에서 함수는 이다. 따라서 함수를 값처럼 취급할 수 있다. 따라서 변수를 복사해 다른 변수에 할당하는 것처럼 함수를 복사해 다른 변수에 할당할 수 있다.

함수 선언문 vs 함수 표현식

1. 문법

// 함수 선언문
function sum(a, b) {
  return a + b; 
}

// 함수 표현식
let sum = function(a, b) {
  return a + b; 
}

함수 선언문 : 함수는 코드 흐름 중간에 독자적인 구문 형태로 존재한다.

함수 표현식 : 표현식이나 구문 구성 내부에 생성된다. 함수의 정의는 할당 연산자 = 우측에 생성된다.

2. 함수 생성 시기

함수 선언문 : 함수 선언문은 정의되기 전에 호출이 가능하다. 함수 선언문 또한 호이스팅이 일어나는데, 호이스팅은 변수와 함수의 선언 을 메모리에 할당한다. 따라서 아래와 같은 코드의 작성이 가능하다.

foo();	// Hello World!
function foo() {
  console.log("Hello World!");
}

함수 표현식 : 함수 표현식은 실제 실행 흐름이 해당 함수에 도달했을 때 함수가 생성이 된다. 따라서 실행 흐름이 함수에 도달했을 때부터 해당 함수를 사용할 수 있다. 여기서 함수를 변수에 할당한다는게 중요한 키워드인 것 같다.
세 가지 예시를 들어보자면,

var foo = function() {
  console.log("Hello World!");
};

foo()  // Hello World!

위의 코드는 정상 작동한다.

foo();	// TypeError: foo is not a function
console.log(foo);	// undefined
var foo() = function() {
  console.log("Hello World!");
};
console.log(foo);	//[Function: foo]

위의 코드는 실행 시 TypeError가 발생한다. foo()를 잠시 주석 처리하고 함수 표현식의 위 아래로 log를 확인하면 차례대로 undefined, [Function: foo]가 출력되는 것을 확인할 수 있다.

그렇다면 let이나 const에 할당한 함수 표현식은 어떨까?

foo(); // ReferenceError: Cannot access 'foo' before initialization
const foo = function () {
  console.log("Hello World!");
};

위의 코드는 var 함수 표현식과 다른 에러를 반환한다. 여기서 확인할 수 있는 건, 함수 표현식의 경우 변수의 호이스팅이 일어난다는 점이다.

3. 스코프

함수 선언문은 "use strict" 사용 여부에 따라 다르게 작동한다.

"use strict";

{
  function foo() {
    console.log("Hello World!");
  }
}

foo();	// ReferenceError: foo is not defined

"use strict"를 사용하면 함수 선언문의 유효 범위는 코드 블록 내부가 된다.

{
  function foo() {
    console.log("Hello World!");
  }
}

foo();	// Hello World!

반면 "use strict" 를 사용하지 않으면 코드 블록 내에서 선언한 함수를 코드 블록 밖에서 사용할 수 있다. 이 부분은 왜 이렇게 사용이 가능한지 좀 더 찾아봐야겠다.

아래 함수 표현식들은 "변수"로 생각하면 그 스코프를 생각하기 쉬워진다.

let foo = function () {
  console.log("Hello");
};

foo();	// Hello
{
  let foo = function () {
    console.log("Hello");
  };
}

foo();  //ReferenceError: foo is not defined

위의 let 혹은 const에 할당한 foo 함수표현식은 코드 블록 {...} 내에서 선언이 되었으므로, 코드 블록 밖에서는 사용할 수 없다

{
  var foo = function () {
    console.log("Hello");
  };
}

foo();	// Hello

반면 var에 할당한 경우, 코드 블록 밖에서도 호출이 가능하다.

참고 자료

https://velog.io/@bisu8018/%ED%95%A8%EC%88%98-%ED%91%9C%ED%98%84%EC%8B%9D-VS-%ED%95%A8%EC%88%98-%EC%84%A0%EC%96%B8%EC%8B%9D
https://ko.javascript.info/function-expressions#ref-255

profile
The best time to plant a tree was twenty years ago. The second best time is now.
post-custom-banner

0개의 댓글