본문 바로가기
JavaScript

[JavaScript] 화살표 함수 vs 일반 함수 – 언제, 왜 다르게 쓸까?

by Caffein not null 2025. 6. 26.

JavaScript에서 함수를 정의하는 방식은 다양하지만,

대표적으로 function 키워드로 만든 일반 함수=> 로 정의하는 화살표 함수가 있습니다.

이 둘을 구분하지 않고 섞어 쓰면 this나 arguments 관련 버그가 생길 수 있습니다.

이번 글에서는 두 함수의 핵심 차이점에 대해 알아보겠습니다.

 

문법 차이와 간결함

기본 단순 함수부터 매개변수 하나, return 생략, 객체 리턴까지 다양한 형태를 직관적으로 비교해보겠습니다.

// 일반 함수
function greet(name) {
  return 'Hello, ' + name;
}

// 함수 표현식
const greet2 = function(name) {
  return 'Hi, ' + name;
}

// 화살표 함수
const greetArrow = (name) => {
  return `Hey, ${name}`;
}

// 매개변수가 하나일 때 ( ) 생략 가능
const greetArrowShort = name => `Hey, ${name}`;

// {}와 return 생략 가능 (한 줄 표현 시)
const sum = (a, b) => a + b;

// 객체 반환 시 괄호 () 필수
const makeUser = (id, name) => ({ id, name });

 

this 바인딩

가장 큰 차이 중 하나는 바로 this의 동작 방식입니다.
this가 무엇을 가리키느냐에 따라 함수의 동작 방식이 완전히 달라지죠.

const user = {
  name: 'Alice',
  sayNameRegular: function() {
    console.log('regular:', this.name);
  },
  sayNameArrow: () => {
    console.log('arrow:', this.name);
  }
};

user.sayNameRegular(); // Alice
user.sayNameArrow();   // undefined

 

  • 일반 함수: this가 해당 객체(user)를 가리킵니다.
  • 화살표 함수: 정의된 스코프(여기선 전역)를 따라 this가 고정됩니다.
📌예시 : 클래스 안에서의 화살표 함수 vs 일반 함수

 

class Counter {
  count = 0;
  regularMethod() {
    setTimeout(function() {
      this.count++;
      console.log('regularMethod count:', this.count);
    }, 100);
  }
  arrowMethod() {
    setTimeout(() => {
      this.count++;
      console.log('arrowMethod count:', this.count);
    }, 100);
  }
}

const c = new Counter();
c.regularMethod(); // NaN, this는 전역
c.arrowMethod();   // 1, this는 인스턴스

 

  • setTimeout 내부의 화살표 함수는 Counter 인스턴스의 this를 그대로 가리켜 올바른 값 갱신이 가능합니다.
  • 일반 함수는 자신의 this가 독립적이라 잘못된 참조로 이어질 수 있습니다.

 

 

arguments 객체

일반 함수는 내부에 arguments 객체를 사용할 수 있죠.
반면 화살표 함수에는 arguments가 없기 때문에 Rest(...args)를 사용해야 합니다.

function sumAll() {
  let total = 0;
  for (let i = 0; i < arguments.length; i++) {
    total += arguments[i];
  }
  return total;
}

const sumAllArrow = (...args) => args.reduce((a, b) => a + b, 0);

console.log(sumAll(1, 2, 3));      // 6
console.log(sumAllArrow(1, 2, 3)); // 6
⚠️ 화살표 함수 내부에서 arguments를 쓰면 ReferenceError가 발생하므로,
✅ 가변 매개변수가 필요할 땐 Rest를 사용하면 됩니다.

 

생성자 함수 사용 여부

function Person(name) {
  this.name = name;
}

const p1 = new Person('Bob'); // OK

const PersonArrow = (name) => {
  this.name = name;
};

const p2 = new PersonArrow('Charlie'); // TypeError

 

  • 일반 함수는 new 키워드를 붙여 생성자처럼 사용할 수 있습니다.
  • 화살표 함수생성자 함수로 사용할 수 없음 → new 사용 시 에러 발생!

 

 

콜백 함수 활용

콜백으로 함수를 넘길 때도 화살표 함수가 더 편리한 면이 있습니다.

const nums = [1, 2, 3];
const doubled1 = nums.map(function(n) {
  return n * 2;
});
const doubled2 = nums.map(n => n * 2);
console.log(doubled1, doubled2);

 

짧고 읽기 쉬워서 함수 내에 로직이 복잡하지 않다면 화살표 함수가 매우 유리합니다.

 

클래스 내부 활용 예시

class TodoApp {
  constructor() {
    this.todos = [];
    document.getElementById('btn').addEventListener('click', () => {
      this.todos.push('할일');
      console.log(this.todos);
    });
  }
}

 

정리

상황 일반 함수 화살표 함수
객체 메서드 정의 시 ✅ 사용 권장 ❌ 피해야 함 (this 문제)
콜백 함수 (map, filter 등) ⚠️ 가능하지만 장황 ✅ 가장 적합
이벤트 핸들러 안쪽 함수 ✅ 설명 필요 ✅ this 유지에 유리
생성자 함수 (new로 사용할 때) ✅ 사용 가능 ❌ 사용 불가
arguments 객체 사용 필요할 때 ✅ 지원됨 ❌ ...args 로 대체해야 함
가독성 중시, 간단한 함수 ⚠️ 다소 장황 ✅ 명확하고 간결한 표현
  • 짧고 간단한 함수, 콜백 ➡️ 화살표 함수
  • 메서드, 생성자, arguments 필요 ➡️ 일반 함수

 

화살표 함수는 코드를 간결하게 만들고, this 바인딩 문제를 줄이는 데 유용합니다.

하지만 모든 상황에서 무조건 사용하는 것은 오히려 문제를 일으킬 수 있습니다.

상황에 맞게 두 함수의 특성을 이해하고 선택하는 것이 중요합니다.