본문 바로가기
언어

Function expressions (JavaScript)

by adawn 2025. 3. 14.

출처 : https://javascript.info/function-expressions

 

Function expressions

 

javascript.info

 

함수 표현식

자바스크립트에서 함수는 "마법 같은 언어 구조"가 아니라 특별한 종류의 값임. 

우리가 이전에 사용했던 문법은 함수 선언(Function Declaration)이라고 함.

:

 

function sayHi() {
  alert( "Hello" );
}

 

반면 , 함수 표현식 (Function Expression)은 함수 표현식을 만드는 또 다른 문법임.

이 문법을 사용하면 어떤 표현식의 중간에서 새로운 함수를 생성할 수 있음. 

예를 들어 :

 

 

let sayHi = function() {
  alert( "Hello" );
};

 

위 코드에서 변수 SayHi에 함수 리터럴 function () { alert("Hello");}가 할당됨. 

즉 할당 표현식의 우변에서 함수가 생성되었으므로 이것은 함수 표현식임.

 

참고 : 함수 표현식에서는 함수 이름을 생략할 수 있음.

이 경우 익명 함수 (anoymous function)가 생성되며 , 위 예제처럼 바로 변수에 할당할 수 있음. 

위의 코드에도 함수의 이름을 따로 설정해주진 않았음. 

 

이와 같이 함수를 즉시 변수에 할당하면 "함수를 생성해서 변수 sayHi에 넣는다 " 는 의미가 됨. 

 

보다 복잡한 상황에서는 함수가 생성되자마자 바로 호출되거나 나중에 실행될 목적으로 스케줄링 될수도 있고 , 어딘가에 저장되지 않아 익명으로 남기도 함. 

 

함수는 값이다 

다시 한번 강조하면 함수가 어떻게 생성되었든 함수는 하나의 값임. 

위의 두 예제 모두 sayHi 변수에 함수를 저장함. 

 

예를 들어 아래와 같이 alert를 사용하여 함수 값을 출력할 수 있음 : 

 

function sayHi() {
  alert( "Hello" );
}

alert( sayHi ); // 함수의 소스 코드(문자열 표현)가 출력됨

 

함수를 실행하는 것이 아니라 alert으로 바로 함수를 호출해도 출력이 됨.

함수 = 값 

 

어떤 언어에서는 함수 이름을 언급할 때 자동으로 실행되지만 자바스크립트는 그렇지 않음.

자바스크립트에서 함수는 값이므로 다른 값들과 동일하게 다룰 수 있음. 

 

예를 들어 함수를 다른 변수에 복사할 수 있음 : 

 

function sayHi() {   // (1) 함수 생성
  alert( "Hello" );
}

let func = sayHi;    // (2) 함수를 복사 (괄호 없이 sayHi를 참조)

func(); // "Hello" 출력 (3) 복사된 함수를 호출
sayHi(); // "Hello" 출력 – 원래 함수도 정상 호출됨

 

위 코드의 동작을 자세히 설명하면 다음과 같음 : 

 

1. (1) 함수 선언문으로 sayHi 함수를 생성하고 , 변수 sayHi에 저장함. 

2. (2) 변수 func에 sayHi 함수를 복사함. 

    주의: 여기서 sayHi 뒤에 괄호가 없으므로 실제 호출이 아니라 함수 자체를 복사하는 것임.

3. (3) 이제 함수는 sayHi() 뿐 아니라 func() 로도 호출할 수 있음.

 

함수 표현식을 사용하여 sayHi를 선언하는 경우도 동일함 : 

 

let sayHi = function() { // (1) 함수 생성
  alert( "Hello" );
};

let func = sayHi;  // (2)
// ...

 

모든 동작은 위와 동일하게 진행됨.

 

왜 세미콜론이 있을까?

함수 표현식은 아래와 같이 할당문 내에서 생성됨 : 

 

let sayHi = function() {
  // ...
};

 

여기서 할당문이 끝나면 세미콜론(;)을 붙임. 

이 세미콜론은 함수 문법의 일부가 아니라 , 단순히 할당문(statement)의 끝을 표시하기 위함임.

예를 들어 , let sayHi = 5; 에서도 세미콜론이 사용되듯이 , 함수 할당에도 동일하게 사용됨.

 

콜백 함수 

함수를 값으로 전달하고 함수 표현식을 사용하는 예제를 좀 더 살펴봄.

다음 예제에서는 세 개의 매개변수를 갖는 함수 ask(question , yes , no)를 작성함 : 

 

question : 질문 퀘스트 

yes : 사용자의 대답이 "예 " 일 때 실행할 함수 

no : 사용자의 대답이 "아니오" 일 때 실행할 함수 

 

function ask(question, yes, no) {
  if (confirm(question)) yes()
  else no();
}

function showOk() {
  alert( "You agreed." );
}

function showCancel() {
  alert( "You canceled the execution." );
}

// 사용 예: 함수 showOk와 showCancel을 인수로 전달
ask("Do you agree?", showOk, showCancel);

 

위 예제에서 ask 함수의 인자로 전달된 showOk와 showCancel은 콜백(callback) 함수라고 부름. 

 

 

 

즉 필요한 시점에 호출될 ( 나중에 "콜백" 되는 ) 함수들임. 

다른 함수의 인자로 전달이 되는 함수를 이야기함. 

 

 

 

함수 표현식을 사용하여 아래와 같이 더 간결하게 작성할 수도 있음 : 

 

function ask(question, yes, no) {
  if (confirm(question)) yes()
  else no();
}

ask(
  "Do you agree?",
  function() { alert("You agreed."); },
  function() { alert("You canceled the execution."); }
);

 

여기서 함수들은 ask 함수 호출 내부에 익명 함수로 선언되며 , 외부에서는 접근할 수 없음. 

이런 방식은 자바스크립트의 자연스러운 코딩 방식 중 하나임.

 

함수는 행동을 나타내는 값이다.

일반 값 ( 문자열 , 숫자 등)은 데이터를 나타냄. 

함수는 하나의 행동(action)을 나타내며 , 변수 간에 전달할 수 있고 필요할 때 실행할 수 있음. 

 

함수 표현식 vs 함수 선언 

두 가지를 구분하는 주요 차이점을 정리하면 다음과 같음.

 

문법상의 차이 

함수 선언(Function Declaration) : 

코드의 주 흐름에서 별도의 문 (statement)으로 선언함 .

 

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

 

따로 선언문 자체가 존재함.

 

함수 표현식 ( Function Expression):

표현식의 일부 (예:할당문)로서 함수를 생성함. 

 

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

 

따로 선언문을 해준것이 아니라 할당문의 일부에서 함수를 생성한걸 이야기하는 것 같음.

 

생성 시점의 차이

함수 표현식 : 

실행 흐름이 해당 표현식에 도달할 때 함수가 생성됨.

즉 할당문 오른쪽에 있는 함수는 실행이 해당 줄에 도달했을 때 만들어지며 , 그 이후에만 사용할 수 있음.

 

함수 선언 : 

자바스크립트 엔진은 스크립트를 실행하기 전에 전역 또는 블록 내의 함수 선언문들을 먼저 처리함.

따라서 함수 선언문은 코드 어디서든 호출할 수 있음.

 

두 가지의 차이점은 JS 엔진이 스크립트를 실행하기 전에 먼저 처리를 하느냐 혹은 실행 흐름이 넘어왔을 때 생성이 되는냐 차이인것 같음.

 

 

 

예를 들어 : 

 

sayHi("John"); // "Hello, John" 출력

function sayHi(name) {
  alert( `Hello, ${name}` );
}

 

위 코드는 정상적으로 작동하는데 , 이는 함수 선언이 스크립트 시작 전에 이미 처리 되었기 때문임.

 

그래서 함수를 위에서 호출하더라도 아래 있는 함수들이 동작하는 것 같음.

 

만약 이것이 함수 표현식이었다면 , 아래와 같이 호출하면 에러가 발생함 : 

 

sayHi("John"); // 에러 발생

let sayHi = function(name) {
  alert( `Hello, ${name}` );
};

 

함수 표현식의 경우엔 이때 함수가 생성되는건데 아래에 있다보니 아직 실행흐름이 넘어오지 않았고 

그러므로 아직 함수가 생성이 되지 않았는데 함수를 호출했으니 함수가 불러와지지 않는다.

 

블록 스코프에서의 차이 

엄격 모드(strict mode)하에서 , 함수 선언문이 코드 블록 내에 있을 경우 그 함수는 해당 블록 내부에서만 유효함.

 

즉, 블록 밖에서는 접근할 수 없음.

 

let age = prompt("What is your age?", 18);

if (age < 18) {
  function welcome() {
    alert("Hello!");
  }
} else {
  function welcome() {
    alert("Greetings!");
  }
}

// 여기서는 welcome()이 정의되어 있지 않음
welcome(); // Error: welcome is not defined

 

이런 경우 함수 표현식을 사용하여 외부 변수에 할당하면 문제를 해결할 수 있음 : 

 

let age = prompt("What is your age?", 18);

let welcome;

if (age < 18) {
  welcome = function() {
    alert("Hello!");
  };
} else {
  welcome = function() {
    alert("Greetings!");
  };
}

welcome(); // 정상 호출됨

 

외부의 변수에 코드 블럭 내의 함수를 할당하여 외부에서도 해당 함수를 이용할 수 있음.

 

또는 삼항 연산자를 사용해 더 간단하게 작성할수도 있음 : 

 

let age = prompt("What is your age?", 18);

let welcome = (age < 18) ?
  function() { alert("Hello!"); } :
  function() { alert("Greetings!"); };

welcome(); // 정상 호출됨

 

언제 함수 선언과 함수 표현식을 선택해야 할까?

일반적으로 함수를 선언할 때는 함수 선언문(Function Declaration) 문법을 우선 고려함.

함수 선언문은 선언 전에 호출할 수 있어 코드 조직에 유리하며 가독성이 좋음. 

 

하지만 , 만약 조건에 따라 함수를 선택하거나 (위의 예시처럼) 함수 선언문이 적합하지 않은 경우에는 함수 표현식(Function Expression) 을 사용하면 됨.

 

아마  조건에 따라서 필요하지 않은 함수들까지 사용할 필욘 없으니까 함수 표현식을 이용하여 최적화를 하는거 같음.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

'언어' 카테고리의 다른 글

JavaScript specials (JavaScript)  (0) 2025.03.15
Arrow functions, the basics (JavaScript)  (0) 2025.03.14
Functions (JavaScript)  (0) 2025.03.14
The "switch" statement (JavaScript)  (0) 2025.03.14
Loops: while and for  (0) 2025.03.14