📚 CS/JavaScript

[JavaScript] 함수 (Function)

dev.daisy 2025. 11. 11. 17:47
JavaScript 함수에 관련된 개념을 공부하면서 익숙하게 사용하던 함수들이 서로 구체적인 차이와 목적을 가지고 있다는 점을 다시 확인할 수 있었습니다. 특히 개발하면서 자주 사용하는 JavaScript에서 함수가 일급 객체로 취급된다는 사실이 고차 함수, 콜백, 함수 조합 같은 패턴을 가능하게 한다는 구조적 특징이라는 점이 가장 인상깊었습니다. 코드 작성 방식이 프로그램 전체의 안정성과 복잡도에 어떻게 기여하는지 다시 생각해 볼 수 있는 시간이었습니다.

1) 함수(Function)

정의

함수는 특정 입력을 받아 내부 로직을 통해 결과를 계산한 뒤 반환하는 실행 단위입니다. 프로그램의 연산을 독립된 블록으로 구성해 재사용할 수 있는 구조를 제공하며, 동일한 로직을 여러 곳에서 호출할 수 있도록 단일 책임 단위로 구성될 때 특히 유용합니다.

 

주의

함수가 외부 상태를 직접 변경하거나 외부 환경에 의존할 경우, 함수 호출만으로 결과를 예상하기 어려워질 수 있습니다. 외부 변수, DOM, 네트워크 요청 등과 상호작용하는 코드는 실행 순서와 환경 변화에 따라 출력이 달라질 수 있으므로 함수 내부의 영향 범위를 명확하게 파악하는 것이 중요합니다.

// 외부 값에 의존하지 않는 함수 (예측 가능)
function square(x) {
  return x * x;
}

// 외부 상태를 읽고 변경하는 함수 (동작 예측이 어려워짐)
let count = 0;
function increase() {
  count++;
}

 

 

2) 함수 선언문(Function Declaration)

정의

함수 선언문은 function과 식별자를 사용해 상위 스코프에 함수를 정의하는 구문입니다. 선언문은 호이스팅되어 실행 단계 이전에 스코프에 바인딩되며, 코드 작성 위치보다 앞에서 호출할 수 있습니다.

 

주의

호이스팅 특성으로 인해 코드의 실제 정의 위치와 실행 가능한 시점이 달라 보일 수 있습니다. 코드 해석 시 선언문이 스코프 맨 위에 있는 것처럼 동작하므로, 실행 흐름과 선언 순서를 명확하게 이해할 필요가 있습니다.

// 선언 이전에도 호출 가능
greet();

function greet() {
  console.log("Hello");
}

 

 

3) 함수 표현식(Function Expression)

정의

함수 표현식은 함수를 값으로 생성하여 변수에 할당하는 형태입니다. 변수는 호이스팅되지만 할당은 런타임에 수행되므로, 초기화가 완료된 후에만 호출할 수 있습니다.

 

주의

할당 이전 호출은 ReferenceError 또는 TypeError를 발생시킬 수 있습니다. 표현식 기반 함수는 정의 순서가 실행 가능 시점에 직접적인 영향을 주므로, 호출 시점을 고려한 구조가 필요합니다.

// console.log(add(3, 4));  // ❌ TypeError

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

console.log(add(3, 4)); // ✅ 7

 

 

4) 화살표 함수(Arrow Function)

정의

화살표 함수는 짧은 문법을 제공하며, 기존 함수와 달리 자체적인 this, arguments, super, new.target을 생성하지 않고 상위 스코프의 값을 그대로 사용합니다. 함수형 패턴이나 콜백에서 간결한 형태로 자주 사용됩니다.

 

주의

동적 this가 필요한 객체 메서드에서는 화살표 함수를 사용하면 this가 기대와 다른 객체를 가리킬 수 있습니다. 또한 화살표 함수에는 arguments 객체가 존재하지 않기 때문에 가변 인자 처리 시 나머지 매개변수(...args)를 사용해야 합니다.

const obj = {
  value: 10,
  // 화살표 함수는 this를 obj로 바인딩하지 않음
  wrong: () => console.log(this.value),
  // 일반 함수는 호출한 객체 기준으로 this 바인딩
  correct() {
    console.log(this.value);
  }
};

obj.wrong();   // undefined
obj.correct(); // 10

 

5) 순수 함수(Pure Function)

정의

순수 함수는 동일한 입력에 대해 항상 동일한 출력을 생성하며, 외부 상태를 변경하지 않는 함수입니다. 내부 연산만으로 결과가 결정되는 구조를 가지기 때문에 예측 가능성이 높고 테스트가 용이합니다.

 

주의

전역 변수 변경, 입력 객체 수정, 시간·난수·I/O 의존 등은 순수 함수의 조건을 충족하지 못합니다. 입력 데이터의 구조가 변경되거나 외부 상태가 바뀌면 동일한 입력이라도 출력이 달라지기 때문에 순수성이 깨지게 됩니다.

// ✅ 순수 함수
function double(x) {
  return x * 2;
}

// ❌ 순수 함수가 아님 (입력 객체 직접 수정)
function addTag(post, tag) {
  post.tags.push(tag);
  return post;
}

 

6) 부수 효과(Side Effect)

정의

부수 효과는 함수가 실행될 때 함수 외부의 상태를 변경하거나, 외부 상태에 의존하여 동작하는 모든 행위입니다. 대표적으로 전역 변수 수정, DOM 조작, 네트워크 요청, 파일 접근 등이 포함됩니다.

 

주의

부수 효과는 함수 실행 순서나 환경에 따라 결과가 달라질 수 있으며, 코드의 흐름을 단독으로 파악하기 어렵게 만드는 요인이 됩니다. 함수가 가진 부수 효과의 종류와 범위를 명확히 아는 것이 중요합니다.

function saveUser(user) {
  // localStorage 활용 = 부수 효과
  localStorage.setItem("user", JSON.stringify(user));
}

 

 

7) 불변성(Immutability)

정의

불변성은 데이터를 직접 변경하지 않고, 변경이 필요할 때 기존 값을 복사하여 새로운 데이터를 생성하는 방식입니다. 원본 데이터는 그대로 유지되고, 변경 사항은 새로운 객체나 배열로 표현됩니다.

 

주의

얕은 복사만으로는 깊은 구조의 객체 내부 참조가 그대로 유지되어 변이가 의도치 않게 전파될 수 있습니다. 중첩된 객체 구조에서는 참조 공유 여부를 파악하는 것이 중요합니다.

const state = { user: { name: "Kim", skills: ["js"] } };

// 불변 업데이트
const next = {
  ...state,
  user: {
    ...state.user,
    skills: [...state.user.skills, "ts"]
  }
};

 

 

8) 일급 함수(First-class Function)

정의

자바스크립트에서 함수는 값으로써 다루어지며, 변수에 저장하거나 다른 함수의 인자로 전달하거나 반환값으로 사용할 수 있습니다. 이러한 특성은 고차 함수, 함수 조합, 커링 등의 패턴을 가능하게 합니다.

 

주의

함수가 값처럼 여러 위치로 전달될 경우 실행 흐름이 분산되어 함수 호출의 순서를 파악하기 어렵습니다. 호출 경로와 함수의 역할이 명확해야 흐름을 추적할 수 있습니다.

const apply = (fn, x) => fn(x);
const triple = x => x * 3;

console.log(apply(triple, 4)); // 12

 

9) 고차 함수(Higher-order Function)

정의

고차 함수는 함수를 인자로 받거나 함수를 반환하는 함수입니다. 반복되는 로직을 추상화하거나 여러 동작을 조합할 수 있는 기반을 제공합니다.

 

주의

고차 함수가 중첩되면 호출 구조가 복잡해질 수 있으며, 내부 함수의 실행 시점과 전달된 함수의 역할을 정확히 이해해야 전체 흐름을 파악할 수 있습니다.

function withLog(fn) {
  return function(value) {
    console.log("input:", value);
    return fn(value);
  };
}

const double = x => x * 2;
const loggedDouble = withLog(double);

loggedDouble(5); // input: 5 → 10

 

10) 익명 함수(Anonymous Function)

정의

익명 함수는 식별자 없이 정의된 함수 표현식입니다. 보통 콜백 자리에서 간단한 로직을 즉시 전달할 때 사용됩니다.

 

주의

함수명 정보가 없어 스택 트레이스나 디버깅 시 위치와 역할을 파악하기 어렵습니다. 동작을 명확하게 추적해야 하는 상황에서는 이름이 있는 함수가 더 적합합니다.

setTimeout(function() {
  console.log("done");
}, 1000);

 

 

11) 기명 함수(Named Function)

정의

기명 함수는 식별자를 가진 함수로, 스택 트레이스에서 이름이 나타나고 재귀 호출 시 자기 자신을 참조하기 용이합니다.

 

주의

함수명이 실제 동작을 설명하지 않으면 코드 해석이 어려워질 수 있습니다. 이름과 기능이 일치하는 구조가 필요합니다.

const factorial = function fact(n) {
  return n <= 1 ? 1 : n * fact(n - 1);
};

 

 

12) 콜백 함수(Callback Function)

정의

콜백 함수는 다른 함수에 인자로 전달되어 특정 시점에 실행됩니다. 배열 메서드, 이벤트 처리, 비동기 흐름 등 다양한 영역에서 사용됩니다.

 

주의

콜백이 깊게 중첩되면 흐름을 따라가기 어려워지고, 에러 처리 방식도 복잡해질 수 있습니다. 실행 시점과 호출 스택을 분리해 이해해야 합니다.

[1, 2, 3].map((value, index) => value + index);

 

 

13) 즉시 실행 함수(IIFE)

정의

즉시 실행 함수는 정의되자마자 즉시 실행되는 함수 표현식입니다. 초기화 작업이나 독립된 스코프가 필요한 로직에 사용됩니다.

 

주의

모듈 스코프가 기본 제공되는 환경에서는 사용 빈도가 낮지만, 즉시 실행 함수가 여러 개 중첩되면 코드 구조가 단절되어 흐름을 파악하기 어렵습니다.

const config = (function () {
  const mode = "production";
  return { mode };
})();

 

키워드

더보기
더보기

함수 (Function)

함수 선언문 / 함수 표현식 / 화살표 함수

순수 함수

부수 효과

불변성

일급 함수 / 일급 시민

고차 함수

익명 함수

함수 표현식

기명 함수

콜백 함수

화살표 함수 (복습)

즉시 실행 함수