MDN에 따르면, 화살표 함수(Arrow Function)는 일반 함수 표현식보다 문법적으로 간결한 대안입니다. 다만 this, arguments, super, new.target 키워드에 대한 자체 바인딩을 가지지 않는다는 점이 특징입니다. 이러한 이유로 화살표 함수는 메서드로 사용하기에는 적합하지 않으며, 생성자(Constructor)로도 활용할 수 없습니다.
그렇다면 자바스크립트에서 일반 함수와 화살표 함수는 구체적으로 어떤 차이가 있을까요? 크게 세 가지 미묘하지만 중요한 차이점이 존재합니다.
1. 자체 this 바인딩이 없다
화살표 함수는 자신만의 this 값을 가지지 않습니다. 화살표 함수 내부에서 참조되는 this는 항상 외부(둘러싼) 스코프에서 상속받은 값입니다.
예제 코드
this.a = 100;
let arrowFunc = () => {this.a = 150};
function regFunc() {
this.a = 200;
}
console.log(this.a)
arrowFunc()
console.log(this.a)
regFunc()
console.log(this.a)
실행 결과
100
150
150
위 결과를 보면 흥미로운 점을 발견할 수 있습니다. 화살표 함수는 자신의 외부 스코프에 있는 this 객체의 값을 직접 변경했습니다. 반면 일반 함수 regFunc()는 자기 자신만의 this 컨텍스트를 새로 만들기 때문에, 외부의 값에는 영향을 주지 못한 것입니다.
2. 자체 arguments 객체가 없다
자바스크립트에서 함수 내부의 arguments 객체는 해당 함수에 전달된 모든 인수를 담고 있는 특수한 객체입니다. 그런데 this와 마찬가지로, 화살표 함수는 자체적인 arguments 바인딩을 가지지 않습니다. 대신 화살표 함수 내부의 arguments는 외부 스코프의 arguments 객체에 바인딩됩니다.
3. 호출은 가능하지만 생성(new)은 불가능하다
함수의 성격을 이해하려면 두 가지 개념을 알아야 합니다.
- Constructible(생성 가능):
new User()처럼new키워드와 함께 호출하여 새로운 객체를 만들 수 있는 경우 - Callable(호출 가능):
new없이 일반적인 방식으로 호출할 수 있는 경우
함수 선언문이나 함수 표현식으로 만든 일반 함수는 생성 가능하면서 동시에 호출 가능합니다. 반면 화살표 함수(그리고 객체 메서드)는 호출만 가능하고, 클래스 생성자는 생성만 가능합니다.
따라서 호출할 수 없는 것을 호출하려 하거나, 생성할 수 없는 것을 new로 생성하려고 시도하면 런타임 에러가 발생합니다.
예제 코드
let arrowFunc = () => {}
new arrowFunc()실행 결과
arrowFunc is not a constructor
위 코드처럼 화살표 함수를 new로 생성하려고 하면 "not a constructor"라는 에러가 발생하는 것을 확인할 수 있습니다.
정리
화살표 함수는 짧고 간결한 문법 덕분에 콜백 함수나 배열 메서드(map, filter 등)에서 매우 유용하게 사용됩니다. 하지만 자체 this와 arguments 바인딩이 없고, 생성자로 사용할 수 없다는 점을 반드시 기억해야 합니다. 객체의 메서드를 정의하거나 생성자 역할이 필요한 경우에는 일반 함수 또는 클래스를 사용하는 것이 올바른 선택입니다.