ES6이전에 사용하던 function
키워드를 이용한 regular function과 ES6에 도입된 arrow function =>
을 비교하고 무엇을 선택해야 하는지 정리해보고자 한다.
Regular function은 호출할 때 This 바인딩을 진행한다. 메소드가 호출했는지 혹은 함수로서 호출했는지에 따라 this를 globalThis
를 가르킬건지 특정 객체를 가르킬건지를 정하게 된다. 하지만 arrow function은 this를 스스로 바인딩 하지 않는다. 단지 생성할 때 가까운 this를 가르키게 된다. 다음의 예를 보자
// this
const regularFunc = function () {
console.log('안녕하세요 나는 ', this, '입니다.');
};
const arrowFunc = () => console.log('안녕하세요 나는 ', this, '입니다.');
const obj = {
introduceRegular: regularFunc,
introduceArrow: arrowFunc,
};
obj.introduceRegular(); // 메소드로서 호출, 안녕하세요 나는 obj입니다.
regularFunc(); // 함수로서 호출, 안녕하세요 나는 window입니다.
obj.introduceArrow(); // 안녕하세요 나는 window입니다.
arrowFunc(); // 안녕하세요 나는 window입니다.
다음과 같이 regularFunc
의 this는 다르게 바인딩 되는 반면 arrowFunc
은 호출 방식에 관계없이 생성당시의 가까운 this를 바인딩하여 globalThis
객체를 가르키게 된다.
regular function은 선언문 전부가 호이스팅 되지만, arrow function은 호이스팅이 일어나지 않는다.
regular(); // Hoisting in javascript
function regular() {
console.log('Hoisting in javascript');
}
arrow(); // arrow is not a function
var arrow = () => {
console.log('function calling');
};
regular function은 생성자 함수로서 작동할 수 있기 때문에 new
키워드를 사용할 수 있다. 하지만 arrow function은 생성자 함수로서 작동할 수 없어서 new
키워드를 통해 호출이 불가능하다.
const Arrow = () => {};
const Regular = function() {}
new Regular(); // O
new Arrow(); // Arrow is not a constructor
실제로 Arrow
와 Regular
를 비교해보면 Regular
에는 prototype프로퍼티에 constructor 프로퍼티가 존재하는 반면, Arrow
는 prototype프로퍼티 조차 존재하지 않는 것을 볼수 있다.
regular function에 존재하는 arguments
를 사용할 수 있지만, arrow function에서는 사용할 수 없다.
const argumentsInArrow = () => {
console.log(arguments);
};
argumentsInArrow(1); // arguments is not defined
const argumentsInRegular = function() {
console.log(arguments);
};
argumentsInRegular(1); // arguments
우선 결론적으로 말하면 arrow function을 주로 사용하고 function
키워드는 generator를 사용할 때만 사용하는 것이 좋다. 이유는 다음과 같다.
function
키워드로 만든 regular function 함수보다 가볍다(this바인딩 제거와 같은 이유로)class
구문을 사용하면 된다.