안녕하세요 여러분! 이 글에서는 자바스크립트에서 매우 유용한 기능 중 하나인 화살표 함수에 대해 설명하려고 합니다.

화살표 함수와 일반 함수 문법을 비교해 보고, 어떻게 쉽게 일반 함수를 화살표 함수로 전환할 수 있는지 보여드리며, 왜 화살표 함수 문법을 일반 함수보다 추천하는지 논의할 것입니다.

다룰 내용은 다음과 같습니다:

화살표 함수 문법이란?

어떻게 쉽게 일반 함수를 화살표 함수로 바꾸나요?

왜 화살표 함수가 일반 함수보다 더 추천되는가

– 짧은 함수에 화살표 함수가 더 좋습니다

– 화살표 함수는 암시적으로 return 문을 가집니다

– 화살표 함수는 this 바인딩이 없습니다

화살표 함수를 사용하지 말아야 할 때는?

결론

자, 시작해봅시다!

화살표 함수 문법이란?

자바스크립트에서 함수를 생성할 필요가 있을 때, 주로 사용하는 방법은 아래와 같이 function 키워드 다음에 함수 이름을 넣어 사용하는 것입니다:

function greetings(name) {
  console.log(`Hello, ${name}!`);
}

greetings('John'); // Hello, John!

일반 자바스크립트 함수인 greetings() 예시입니다.
화살표 함수 문법은 위와 동일한 결과를 생산하는 함수 표현식을 생성할 수 있도록 합니다.

다시 greetings() 함수를 화살표 함수 문법을 이용해 보겠습니다:

const greetings = name => {
  console.log(`Hello, ${name}!`);
};

greetings('John'); // Hello, John!

화살표로 작성된 greetings() 함수 버전입니다.
화살표 함수 문법으로 함수를 선언할 때, 선언을 변수에 할당해서 함수가 이름을 가지도록 해야 합니다.

기본적으로 화살표 함수 문법은 다음과 같이 보입니다:

const myFunction = (param1, param2, ...) => {
  // 함수 본문
}

화살표 함수 문법 예시입니다.
위 코드에서 myFunction은 함수를 가지고 있는 변수입니다. 코드의 후반부에서 myFunction()으로 함수를 호출할 수 있습니다.

(param1, param2, ...)은 함수의 매개변수들입니다. 함수가 필요로 하는 만큼 많은 매개변수를 정의할 수 있습니다.

그러고 나서 => 화살표를 사용하여 함수의 시작을 나타냅니다. 그 다음에는 중괄호 {}를 사용하여 함수 본문을 표시하거나, 단일 라인 함수라면 중괄호를 생략할 수 있습니다. 이에 대해서는 나중에 좀 더 설명하겠습니다.

처음에는 화살표 함수가 함수 키워드를 볼 때와는 달리 이상하게 느껴질 수 있습니다. 하지만 화살표 문법을 쓰기 시작하면 훨씬 편리하고 쓰기 쉽다는 것을 알게 될 겁니다.

다음으로, 어떻게 쉽게 일반 함수를 화살표 함수로 전환하는지 보여드리겠습니다.

어떻게 쉽게 일반 함수를 화살표 함수로 바꾸나요?

일반 함수를 화살표 함수로 전환하기 위해서는 다음 세 간단한 단계를 따르면 됩니다:

  1. function 키워드를 변수 키워드 const로 대체합니다
  2. 함수 이름 뒤와 괄호 앞에 = 기호를 추가합니다
  3. 괄호 뒤에 => 기호를 추가합니다
    보통 함수는 선언 후에 변경되지 않으므로 const 키워드를 let 대신 사용합니다.

아래 코드가 단계들을 시각화해주는 데 도움이 될 것입니다:

// 원래 함수 
function greetings(name) {
  return `Hello, ${name}!`;
}

// 1단계: function을 const로 교체
const greetings(name) {
  return `Hello, ${name}!`;
}

// 2단계: 함수 이름 뒤에 = 추가
const greetings = (name) {
  return `Hello, ${name}!`;
}

// 3단계: 괄호 뒤에 => 추가
const greetings = (name) => {
  return `Hello, ${name}!`;
}

일반 함수를 화살표 함수로 바꾸는 단계들입니다.
위의 세 단계로 모든 구식 자바스크립트 함수 문법을 새로운 화살표 함수 문법으로 전환할 수 있습니다.

단일 라인 함수를 가질 때는 중괄호와 return 키워드를 제거하는 제4의 선택사항이 있습니다:

// 이렇게
const greetings = (name) => {
  return `Hello, ${name}!`;
};

// 저렇게
const greetings = (name) => `Hello, ${name}!`;

함수 본문을 둘러싼 중괄호 제거입니다.
정확히 하나의 매개변수가 있을 경우, 괄호도 생략할 수 있습니다:

// 이렇게
const greetings = (name) => `Hello, ${name}!`;

// 저렇게
const greetings = name => `Hello, ${name}!`;

매개변수를 둘러싼 괄호 제거입니다.
그러나 마지막 두 단계는 선택적입니다. 함수를 화살표 함수 문법으로 전환하기 위해서는 첫 세 단계만 필요합니다.

왜 화살표 함수가 일반 함수보다 더 추천되는가

화살표 함수 문법은 자바스크립트에서 함수를 작성하는 방식에 몇 가지 개선점을 제공합니다:

  • 한 줄의 짧은 함수를 더 직관적으로 작성할 수 있습니다
  • 단일 라인 함수의 경우, return 문이 암시적일 수 있습니다
  • this 키워드가 함수에 바인딩되지 않습니다
    다음으로 이런 개선점들이 실제 예시로 어떻게 작동하는지 보겠습니다.

짧은 함수에 화살표 함수가 더 좋습니다

콘솔에 문자열을 출력하는 단일 라인 함수를 가진다고 가정해 봅시다. function 키워드를 이용하면, 함수를 다음과 같이 작성하게 됩니다:

function greetings(name) {
  console.log(`Hello, ${name}!`);
}

단일 라인 문을 가진 일반 함수 예시입니다.
화살표 함수 문법을 사용하면, 중괄호를 생략하여 단일 라인 함수를 다음과 같이 만들 수 있습니다:

const greetings = (name) => console.log(`Hello, ${name}!`);

단일 라인 화살표 함수 예시입니다.
게다가 정확히 하나의 매개변수가 있을 경우, 함수 매개변수를 둘러싸는 괄호도 생략할 수 있습니다:

const greetings = name => console.log(`Hello, ${name}!`);

정확히 하나의 매개변수가 있을 때 매개변수 주위의 괄호 제거 예시입니다.
함수 매개변수가 하나도 없을 경우, 할당과 화살표 문법 사이에 비어 있는 괄호를 전달해야 합니다:

const greetings = () => console.log(`Hello, World!`);

매개변수 없는 단일 라인 화살표 함수 예시입니다.
화살표 함수 문법을 사용하면, 함수가 한 줄 이상일 때만 중괄호가 필요합니다. 예를 들면:

const greetings = () => {
  console.log('Hello World!');
  console.log('How are you?');
};

함수 본문을 나타내는 중괄호가 필요한 다중 라인 화살표 함수 예시입니다.
일반 function 키워드를 사용할 때는 상황에 관계 없이 중괄호를 생략할 수 없습니다.

화살표 함수는 함수에 이름을 지정할 필요가 없는 상황, 즉 콜백과 같은 상황에도 아주 좋습니다:

const myArray = [1, 2, 3];

// 이렇게:
myArray.forEach(function (item) {
  console.log(item);
});

// 저렇게:
myArray.forEach(item => console.log(item));

화살표 함수로 생성된 콜백 함수 예시입니다.
또는 즉각적으로 호출되는 함수 표현(IIFE)을 생성할 때 화살표 함수가 좋습니다:

// 이렇게:
(function () {
  console.log('Hello World');
})();

// 저렇게:
(() => console.log('Hello World'))();

화살표 함수로 생성된 즉각적으로 호출되는 함수 표현 예시입니다.
보시다시피 화살표 함수 문법을 사용하면 코드를 훨씬 더 깔끔하고 간결하게 만들 수 있습니다.

화살표 함수는 암시적으로 return 문을 가집니다

단일 라인 화살표 함수를 가질 때, return 문은 자바스크립트에 의해 암시적으로 추가됩니다. 이는 return 키워드를 명시적으로 추가하지 않아도 된다는 의미입니다.

예를 들어 두 숫자를 더하는 함수가 있다고 가정해 보겠습니다:

function sum(a, b) {
  return a + b;
}

값을 반환하는 일반 함수 예시입니다.
위의 함수를 화살표 함수 문법을 사용하여 작성하면, 중괄호와 return 키워드를 제거해야 합니다:

const sum = (a, b) => a + b;

암시적인 return 문을 가진 단일 라인 화살표 함수 예시입니다.
return 키워드를 제거하지 않으면, 자바스크립트는 오류를 발생시키며 중괄호 {를 기대한다고 알려줄 것입니다.

화살표 함수를 사용할 때는 return 문을 여러 줄에 걸친 문장을 작성할 때만 명시적으로 작성합니다:

const sum = (a, b) => {
  const result = a + b;
  return result;
};

여러 줄에 걸친 화살표 함수에서는 return 문이 있는 경우 항상 선언해야 합니다.
중괄호를 제거할 때 return 키워드를 사용한다면 그것도 제거하는 것을 잊지 마세요.

화살표 함수는 this 바인딩이 없습니다

화살표 함수와 일반 함수 문법 사이의 중요한 차이점 중 하나는 this 키워드를 다루는 방식에 있습니다.

일반 함수에서 this 키워드는 함수를 호출한 객체를 가리킵니다. 화살표 함수에서 this 키워드는 함수를 정의한 객체를 가리킵니다.

제가 말하는 것을 보여드리기 위해, 다음과 같은 특성과 메소드를 가진 사람 객체가 있다고 상상해 보겠습니다:

const person = {
  name: 'Nathan',
  skills: ['HTML', 'CSS', 'JavaScript'],

  showSkills() {
    this.skills.forEach(function (skill) {
      console.log(`${this.name}은 ${skill}에 능숙합니다.`);
    });
  },
};

person.showSkills();

forEach() 내의 콜백에서 일반 함수 문법을 사용한 예시입니다.
위 코드를 실행하면, showSkills() 메소드 호출 결과는 다음과 같습니다:

undefined은 HTML에 능숙합니다
undefined은 CSS에 능숙합니다
undefined은 JavaScript에 능숙합니다
this 이름 속성이 정의되어 있지 않습니다.
여기서 this 키워드는 우리가 person 객체 바깥에서 showSkills() 메소드를 호출했기 때문에 전역 Window 객체를 참조합니다.

전역 객체에서 name 속성은 정의되어 있지 않습니다. 이제 콜백 함수를 화살표 문법을 사용하여 다시 작성해 보겠습니다:

const person = {
  name: 'Nathan',
  skills: ['HTML', 'CSS', 'JavaScript'],

  showSkills() {
    this.skills.forEach(skill => {
      console.log(`${this.name}은 ${skill}에 능숙합니다.`);
    });
  },
};

person.showSkills();

forEach() 내의 콜백에서 화살표 함수를 사용한 예시입니다.
코드를 다시 실행하면 결과는 다음과 같을 것입니다:

Nathan은 HTML에 능숙합니다
Nathan은 CSS에 능숙합니다
Nathan은 JavaScript에 능숙합니다
새로운 코드 출력 예시입니다.
여기서 this 키워드는 화살표 함수가 정의된 객체인 person 객체를 참조합니다.

이 한 가지 행동이 바로 사람들이 화살표 함수를 선호하는 이유입니다. 왜냐하면 함수를 호출한 것에서가 아닌 정의한 객체에서 this를 가리키는 것이 더 합리적이기 때문입니다.

화살표 함수를 사용하지 말아야 할 때는?

화살표 함수는 일반 함수보다 선호되는 경우가 많지만, 화살표 함수를 사용하면 안 되는 몇 가지 상황이 있습니다.

객체 메소드를 정의할 때

위의 person 객체 예제로 돌아가 보죠. 만약 당신이 showSkills() 메소드를 화살표 함수로 작성한다면 이렇게 됩니다:

const person = {
  name: 'Nathan',
  skills: ['HTML', 'CSS', 'JavaScript'],

  showSkills: () => {
    this.skills.forEach(skill => {
      console.log(`${this.name}은(는) ${skill}에 능숙합니다.`);
    });
  },
};

person.showSkills();

화살표 함수를 사용한 객체 메소드의 예

위 코드를 실행하면 다음과 같은 오류가 발생합니다:

TypeError: Cannot read properties of undefined (reading 'forEach')

화살표 함수로 인해 발생한 오류 메시지

객체 내부에서 this 키워드는 일반적인 문법(methodName() 또는 methodName: function(){ })으로 메소드를 선언할 때만 현재 객체를 참조합니다.

화살표 함수를 사용하여 객체 메소드를 선언하면 this 키워드는 전역 객체를 참조하며, 그곳에서 skills 속성은 정의되지 않았습니다. 메소드를 선언할 때는 절대 화살표 함수를 사용하지 마세요.

결론

이렇게 화살표 함수에 대해 알아보았습니다. 이제 화살표 함수와 일반 함수의 차이점을 알아보았고, 일반 함수를 화살표 함수로 변환하는 방법도 배웠으며, 화살표 함수를 권장하는 경우(그리고 권장하지 않는 경우!)도 알게 되었습니다.

화살표 함수는 간단한 연산에 대한 inline 함수를 쉽게 작성하고 콜백함수에도 매우 적합한 함수 정의 방법입니다. 하지만 이에 대해 잘 모르다면 다른 사람의 코드를 살펴 볼 때 이해가 어려울 수 있으니 자세히 알아 놓는 것이 중요합니다.