화살표 함수 구문은 ECMAScript 2015의 출시와 함께 등장했으며, 오늘날 화살표 함수는 많은 자바스크립트 프로그래머가 선호하는 기능이 되었습니다. 화살표 함수에 대한 이러한 사랑은 “this” 키워드의 간결한 구문과 직관적인 동작 때문입니다.

하지만 화살표 함수에는 몇 가지 단점이 있습니다. 화살표 함수와 일반 함수의 주요 차이점에 대해 알아보고 대부분의 경우 일반 함수를 사용하는 것이 더 나은 이유를 알아보세요.

화살표 함수를 사용하기 전에 정의해야 합니다

화살표 함수를 띄울 수 없습니다. 자바스크립트의 기본 호이스트 규칙에 따르면 함수를 정의하기 전에 함수를 호출할 수 있지만 화살표 함수는 그렇지 않습니다. 함수가 포함된 JavaScript 파일이 있는 경우 중요한 코드가 모두 파일 맨 아래에 있다는 뜻입니다.

 const doubleNumbers = (numbers) { 
  numbers.map(n => n * 2)
}

const halveNumbers = (numbers) {
  numbers.map(n => n / 2)
}

const sumNumbers = (numbers) {
  numbers.reduce((sum, n) => {
    return sum + n;
  }, 0)
}

const numbers = [1, 20, 300, 700, 1500]
const doubled = doubleNumbers(numbers)
console.log(halveNumbers(doubled))
console.log(sumNumbers(numbers))

위 코드 블록에서는 중요한 코드가 맨 아래에 있습니다. 헬퍼 함수는 모두 실행 시점 이전에 정의되어 있습니다. 파일 맨 위에 자바스크립트 함수를 만들면 작업을 수행하는 실제 코드를 보려면 아래로 스크롤해야 하므로 불편할 수 있습니다.

헬퍼 함수를 맨 아래로, 실제 코드를 맨 위로 이동하면 참조 오류가 발생합니다. 런타임은 함수를 변수로 취급합니다. 따라서 액세스하거나 호출하기 전에 먼저 정의해야 합니다. 하지만 모든 화살표 함수를 일반 함수(함수 키워드 사용)로 변환하면 코드가 정상적으로 작동합니다. 동시에 중요한 코드는 사용자가 찾을 수 있는 상단에 유지됩니다.

이것은 화살표 함수를 사용할 때 가장 큰 문제 중 하나입니다. 호스팅 동작이 전혀 나타나지 않습니다. 즉, 실제 사용할 위치보다 먼저 정의해야 합니다. 반면에 일반 함수는 호스팅할 수 있습니다.

화살표 함수는 어떤 사람들에게는 혼란스러울 수 있음

화살표 함수 대신 일반 함수를 사용하는 또 다른 이유는 가독성입니다. 일반 함수는 함수 키워드를 명시적으로 사용하기 때문에 읽기 쉽습니다. 이 키워드는 해당 코드가 함수임을 식별합니다.

이 글도 확인해 보세요:  GitHub 코파일럿의 이점이 잠재적인 단점을 감수할 가치가 있을까요?

반면에 화살표 함수는 변수에 할당합니다. 초보자라면 코드가 함수가 아니라 변수라고 생각하여 혼동할 수 있습니다.

아래 두 함수를 비교해 보세요:

 const halveNumbers = (numbers) => {
  return numbers.map(n => n / 2)
}

function halveNumbers(numbers) {
  return numbers.map(n => n / 2)
}

언뜻 보면 두 번째 코드 덩어리가 함수라는 것을 쉽게 알 수 있습니다. 구문을 보면 코드가 함수임을 분명히 알 수 있습니다. 그러나 첫 번째는 모호해서 변수인지 함수인지 쉽게 구분할 수 없습니다.

화살표 함수를 메서드로 사용할 수 없습니다

화살표 함수를 사용할 때 이 키워드는 우리가 안에 있는 것의 외부에 해당하는 것입니다. 대부분의 경우 창 객체입니다.

다음 객체를 생각해 보세요:

 const person = {
  firstName: "Kyle",
  lastName: "Cook",
  printName: () => {
    console.log(`${this.firstName}` `${this.lastName}` )
  }
}

person.printName()

코드를 실행하면 브라우저에서 이름과 성이 모두 정의되지 않은 상태로 인쇄되는 것을 확인할 수 있습니다. 화살표 함수를 사용하고 있으므로 이 키워드는 창 객체에 해당합니다. 또한 이름 또는 성 속성이 정의되어 있지 않습니다.

이 문제를 해결하려면 대신 일반 함수를 사용해야 합니다:

 const person = {
  firstName: "Kyle",
  lastName: "Cook",
  printName: function() {
    console.log(`${this.firstName}` `${this.lastName}` )
  }
}

person.printName()

이것은 사람 객체를 참조하기 때문에 잘 작동합니다. 이런 종류의 객체 지향 프로그래밍을 많이 할 예정이라면 일반 함수를 사용하고 있는지 확인해야 합니다. 화살표 함수는 작동하지 않습니다.

화살표 함수를 사용해야 하는 경우

화살표 함수는 주로 익명 함수가 필요한 곳에서 사용하세요. 이러한 시나리오의 예로는 콜백 함수를 처리하는 경우를 들 수 있습니다. 콜백을 작성할 때는 전체 함수를 작성하는 것보다 구문이 훨씬 간단하므로 화살표 함수를 사용하는 것이 좋습니다.

이 두 가지를 비교하여 어느 것이 더 간단한지 결정하세요:

 function halveNumbers(numbers) {
  return numbers.map(n => n / 2)
}

function halveNumbers(numbers) {
  return numbers.map(function(n) {
    return n / 2
  })
}

두 경우 모두 map() 메서드에 콜백 함수를 전달합니다. 하지만 첫 번째 콜백은 화살표 함수이고 두 번째 콜백은 전체 함수입니다. 첫 번째 함수가 두 번째 함수보다 코드 줄이 3개와 5개로 더 적은 것을 볼 수 있습니다.

이 글도 확인해 보세요:  Reqwest로 Rust에서 HTTP 요청 만들기

화살표 함수를 사용하는 다른 경우는 특정 “this” 구문을 처리할 때입니다. 특정 사물에 일반 함수를 사용하는지 화살표 함수를 사용하는지에 따라 “이” 객체가 변경됩니다.

다음 코드 블록은 문서 객체에 두 개의 “클릭” 이벤트 리스너를 등록합니다. 첫 번째 인스턴스는 일반 함수를 콜백으로 사용하고 두 번째 인스턴스는 화살표 함수를 사용합니다. 두 콜백 모두에서 코드가 실행 개체(this)와 이벤트 대상을 기록합니다.

 document.addEventListener("click", function(e) {
  console.log("FUNCTION", this, e.target)
})

document.addEventListener("click", (e) => {
  console.log("ARROW", this, e.target)
})

이 스크립트를 실행해 보면 “this” 참조가 둘 다 다르다는 것을 알 수 있습니다. 일반 함수의 경우 이 속성은 e.target 속성과 동일한 문서를 참조합니다. 그러나 화살표 함수의 경우 이 속성은 창 개체를 참조합니다.

일반 함수를 콜백으로 사용하는 경우 이벤트를 트리거하는 요소를 참조합니다. 그러나 화살표 함수를 사용하는 경우 이 키워드는 기본적으로 창 객체를 참조합니다.

화살표 함수와 일반 함수에 대해 자세히 알아보기

일반 함수와 화살표 함수에는 몇 가지 다른 미묘한 차이점이 있습니다. 두 가지 유형의 함수를 모두 마스터하는 것은 자바스크립트를 숙달하기 위한 기초입니다. 언제 어느 함수를 사용해야 하는지, 언제 다른 함수를 사용해야 하는지 알아보고 자바스크립트에서 일반 함수나 화살표 함수를 사용할 때 어떤 의미가 있는지 이해해 보세요.

By 김민수

안드로이드, 서버 개발을 시작으로 여러 분야를 넘나들고 있는 풀스택(Full-stack) 개발자입니다. 오픈소스 기술과 혁신에 큰 관심을 가지고 있고, 보다 많은 사람이 기술을 통해 꿈꾸던 일을 실현하도록 돕기를 희망하고 있습니다.