자바스크립트에서 함수를 만드는 방법이 세 가지나 되다 보니, 면접에서 "차이점이 뭔가요?"라는 질문이 정말 자주 나옵니다. 핵심은 **호이스팅 **, **this 바인딩 **, arguments 객체 세 가지입니다.

세 가지 함수 정의 방식

JS
// 1. 함수 선언문 (Function Declaration)
function greet(name) {
  return `안녕, ${name}!`;
}

// 2. 함수 표현식 (Function Expression)
const greet2 = function (name) {
  return `안녕, ${name}!`;
};

// 3. 화살표 함수 (Arrow Function)
const greet3 = (name) => `안녕, ${name}!`;

호이스팅 차이

함수 선언문만 호이스팅됩니다. 이것이 첫 번째 핵심 차이입니다.

JS
// 함수 선언문 — 선언 전에 호출 가능
sayHello(); // "hello" ← 정상 동작
function sayHello() {
  console.log("hello");
}

// 함수 표현식 — 선언 전에 호출 불가
sayBye(); // ReferenceError (let) 또는 TypeError (var)
const sayBye = function () {
  console.log("bye");
};

// 화살표 함수 — 함수 표현식과 동일
sayHi(); // ReferenceError
const sayHi = () => console.log("hi");

면접에서 "함수 표현식은 호이스팅되나요?"라고 물어보면, 변수 선언 자체는 호이스팅되지만 ** 할당은 호이스팅되지 않는다 **고 답하면 됩니다.

this 바인딩 — 가장 중요한 차이

JS
const user = {
  name: "정훈",
  // 일반 함수: this는 호출한 객체
  greet() {
    console.log(`안녕, ${this.name}`);
  },
  // 화살표 함수: this는 상위 스코프의 this
  greetArrow: () => {
    console.log(`안녕, ${this.name}`); // this는 user가 아님!
  },
};

user.greet();      // "안녕, 정훈"
user.greetArrow(); // "안녕, undefined" — this가 전역 객체를 가리킴

화살표 함수는 자신만의 this를 갖지 않고 ** 렉시컬 스코프의 this**를 사용합니다. 이 특성 때문에 객체의 메서드로는 화살표 함수를 쓰면 안 됩니다.

화살표 함수가 유리한 경우

JS
const timer = {
  seconds: 0,
  start() {
    // 화살표 함수가 적합한 경우: 콜백에서 외부 this 유지
    setInterval(() => {
      this.seconds++; // this가 timer를 가리킴
      console.log(this.seconds);
    }, 1000);
  },
};

// 만약 일반 함수를 쓰면 this가 window를 가리킴
const timerBroken = {
  seconds: 0,
  start() {
    setInterval(function () {
      this.seconds++; // this === window — 의도와 다름
    }, 1000);
  },
};

arguments 객체

JS
// 일반 함수: arguments 사용 가능
function sum() {
  return [...arguments].reduce((a, b) => a + b, 0);
}
console.log(sum(1, 2, 3)); // 6

// 화살표 함수: arguments 없음
const sumArrow = () => {
  console.log(arguments); // ReferenceError
};

// 대신 rest 파라미터를 사용
const sumRest = (...args) => args.reduce((a, b) => a + b, 0);
console.log(sumRest(1, 2, 3)); // 6

new 키워드 사용 가능 여부

JS
// 함수 선언문/표현식: 생성자로 사용 가능
function Person(name) {
  this.name = name;
}
const p = new Person("정훈"); // OK

// 화살표 함수: 생성자로 사용 불가
const PersonArrow = (name) => {
  this.name = name;
};
const p2 = new PersonArrow("정훈"); // TypeError: not a constructor

화살표 함수는 prototype 프로퍼티가 없어서 new와 함께 사용할 수 없습니다.

화살표 함수의 간결한 문법

JS
// 매개변수가 하나면 괄호 생략 가능
const double = x => x * 2;

// 객체 리터럴 반환 시 소괄호로 감싸기
const makeUser = (name) => ({ name, createdAt: Date.now() });

// 본문이 여러 줄이면 중괄호 + return 필요
const calculate = (a, b) => {
  const sum = a + b;
  const avg = sum / 2;
  return avg;
};

상황별 선택 가이드

상황추천 방식이유
일반 유틸 함수함수 선언문호이스팅으로 코드 순서 자유로움
콜백 함수화살표 함수간결하고 this 문제 없음
객체 메서드메서드 축약 (greet() {})this가 객체를 가리킴
생성자함수 선언문 (or class)화살표 함수는 생성자 불가
이벤트 핸들러일반 함수this가 이벤트 대상 요소
React 컴포넌트화살표 함수 (컨벤션)팀 컨벤션에 따름

정리

PLAINTEXT
함수 선언문:  호이스팅 O | 자체 this O | arguments O | new O
함수 표현식:  호이스팅 X | 자체 this O | arguments O | new O
화살표 함수:  호이스팅 X | 자체 this X | arguments X | new X

**기억하기 **: "화살표 함수는 가볍지만 this, arguments, new가 없다." 이 한 문장을 기억하면 면접에서 당황하지 않습니다. 콜백에는 화살표, 메서드에는 일반 함수가 안전한 선택입니다.

댓글 로딩 중...