[JavaScript] Function과 Arrow Function의 차이

정예원·2021년 8월 18일
1

JavaScript

목록 보기
6/13
post-thumbnail
post-custom-banner

수업을 듣던 중 특정 부분에서 Arrow Function을 사용하면 에러가 발생하는 것을 발견하였다.
과연 Function과 Arrow Function은 무슨 차이가 있길래 이런 현상이 발생하는 것일까?

Arrow Function 이란?

  • ES6부터 추가된 표현
  • Function 표현에 비해 구문이 짧다.
  • 자신의 this, arguments, super 또는 new.target을 바인딩 하지 않는다.
  • 항상 익명 함수이다.
  • 메소드 함수가 아닌 곳에 적합하다. 그래서 생성자로 사용할 수 없다.

기본 구문

(param1, param2,, paramN) => { statements }
(param1, param2,, paramN) => expression
// 다음과 동일함:  => { return expression; }

// 매개변수가 하나뿐인 경우 괄호는 선택사항:
(singleParam) => { statements }
singleParam => { statements }

// 매개변수가 없는 함수는 괄호가 필요:
() => { statements }

예시

var elements = [
  'Hydrogen',
  'Helium',
  'Lithium',
  'Beryllium'
];

// 이 문장은 배열을 반환함: [8, 6, 7, 9]
elements.map(function(element) {
  return element.length;
});

// 위의 일반적인 함수 표현은 아래 화살표 함수로 쓸 수 있다.
elements.map((element) => {
  return element.length;
}); // [8, 6, 7, 9]

// 파라미터가 하나만 있을 때는 주변 괄호를 생략할 수 있다.
elements.map(element => {
  return element.length;
}); // [8, 6, 7, 9]

// 화살표 함수의 유일한 문장이 'return'일 때 'return'과
// 중괄호({})를 생략할 수 있다.
elements.map(element => element.length); // [8, 6, 7, 9]
f();  // 6

Arrow Function을 사용하면 안되는 경우

1. 메서드 (method)

화살표 함수는 Lexical this를 지원하므로 콜백 함수로 사용하기 편리하다. 하지만 화살표 함수를 사용하는 것이 오히려 혼란을 불러오는 경우도 있으므로 주의하여야 한다.

우선 Arrow Function을 사용하면 안되는 나쁜 예를 살펴보자.

const cat = {
    name: 'bbotto',
    sayHi: () => console.log('Hi ${this.name}'),
}

cat.sayHi()

해당 코드를 실행하면 Hi undefined가 출력된다.
메서드로 정의한 Arrow Function 내부의 this는 메서드를 소유한 객체, 즉 메서드를 호출한 객체를 가리키지 않고 상위 컨텍스트인 전역 객체 window를 가리킨다.

다음으로 Function을 사용한 좋은 예를 살펴보자.

const cat = {
    name: 'bbotto',
    sayHi() {
        console.log('Hi ${this.name}')
    },
}

cat.sayHi()

Function을 사용한 코드를 실행하면 Hi bbotto로 원하는 결과가 출력된다.

2. 프로토타입 (prototype)

화살표 함수로 정의된 메소드를 prototype에 할당하는 경우도 동일한 문제가 발생한다. 화살표 함수로 정의된 메소드를 prototype에 할당하여 보자.

Arrow Function

const cat = {
    name: 'bbotto',
}

Object.prototype.sayHi = () => console.log(`Hi ${this.name}`)
cat.sayHi()

위 코드를 실행하면 Hi undefined가 출력된다.
이유는 1번과 마찬가지로 window를 가리키기 때문이다.

Function

const cat = {
    name: 'bbotto',
}

Object.prototype.sayHi = function() {
  console.log(`Hi ${this.name}`)
}
cat.sayHi()

코드를 실행하면 Hi bbotto로 원하는 결과가 출력된다.

3. 생성자 함수 (constructor)

화살표 함수는 생성자 함수로 사용할 수 없다. 생성자 함수는 prototype 프로퍼티를 가지며 prototype 프로퍼티가 가리키는 프로토타입 객체의 constructor를 사용한다.
하지만 화살표 함수는 prototype 프로퍼티를 가지고 있지 않다.

const Foo = () => {};

// 화살표 함수는 prototype 프로퍼티가 없다
console.log(Foo.hasOwnProperty('prototype')); // false

const foo = new Foo(); // TypeError: Foo is not a constructor

4. addEventLister의 콜백함수에서 this를 사용하는 경우

addEventListener 함수의 콜백 함수를 화살표 함수로 정의하면 this가 상위 컨택스트인 전역 객체 window를 가리킨다.

const $button1 = document.getElementById('button1');

$button1.addEventListener('click', () => {
  console.log(this === window); // => true
  this.innerHTML = 'Clicked button';
});

this는 window를 가리킨다.

const $button1 = document.getElementById('button1');

$button1.addEventListener('click', function() {
  console.log(this === window); // => false
  this.innerHTML = 'Clicked button';
});

일반 함수로 정의된 addEventListener 함수의 콜백 함수 내부의 this이벤트 리스너에 바인딩된 요소(currentTarget)를 가리킨다.

Reference

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Functions/Arrow_functions
https://poiemaweb.com/es6-arrow-function

profile
hello world!
post-custom-banner

0개의 댓글