화살표 함수는 단순히 함수를 짧게 쓰는 용도로 사용되지 않는다.
javascript에서는 함수를 생성하고 그 함수를 어딘가에 전달한다.
ex) arr.forEach(func)
, setTimeout(func)
등...
어딘가에 함수를 전달하게 되면 함수의 컨텍스트를 잃을 수 있는데 화살표 함수를 사용하면 현재 컨텍스트를 잃지 않는다.
화살표 함수 본문에서 this
에 접근하면 외부에서 값을 가져온다.
이런 특징은 객체의 메소드(showList()
) 안에서 동일 객체의 프로퍼티(students
)를 대상으로 순회를 하는 데 사용할 수 있다.
let group = {
title: "1모둠",
students: ["철수", "영희", "훈"],
showList() {
this.students.forEach(
student => console.log(this.title + ': ' + student)
);
}
};
group.showList();
예시의 forEach
에서 화살표 함수를 사용했기 때문에 화살표 함수 본문에 있는 this.title
은 화살표 함수 바깥에 있는 메서드인 showList
가 가리키는 대상과 동일해진다. 즉 this.title
은 group.title
과 같다.
위를 화살표 함수가 아닌 일반 함수로 사용했으면this
가 undefined
로 발생할 것이다. undefined.title
에 접근하려 했기 때문에 에러가 발생하는 것이다. 하지만 화살표 함수는this
자체가 없기에 이런 에러가 발생하지 않는다.
※ 화살표 함수는 new
와 함께 사용할 수 없다. this
가 없기 때문이다.
※ 화살표 함수 vs. bind
화살표 함수와 일반 함수를 .bind(this)
를 사용해서 호출하는 것 사이에는 미묘한 차이가 있다.
.bind(this)
는 함수의 '한정된 버전(bound version)'을 만든다.
화살표 함수는 어떤 것도 바인딩시키지 않는다. 화살표 함수엔 단지 this가 없을 뿐이다.
화살표 함수는 일반 함수와 다르게 모든 인수에 접근할 수 있게 해주는 유사 배열 객체 arguments
를 지원하지 않는다.
이런 특징을 현재 this
값 과 arguments
정보를 함께 실어 호출을 포워딩 해주는 데코레이터를 만들 때 유용하게 사용 된다.
function defer(f, ms) {
return function() {
setTimeout(() => f.apply(this, arguments), ms)
};
}
function sayHi(who) {
console.log('안녕, ' + who);
}
let sayHiDeferred = defer(sayHi, 2000);
sayHiDeferred("철수"); // 2초 후 "안녕, 철수"가 출력
화살표 함수를 사용하지 않고 동일한 기능을 하는 데코레이터 함수를 만들면 다음과 같다.
function defer(f, ms) {
return function(...args) {
let ctx = this;
setTimeout(function() {
return f.apply(ctx, args);
}, ms);
};
}
일반 함수에선 setTimeout
에 넘겨주는 콜백 함수에서 사용할 변수 ctx
와 args
를 반드시 만들어줘야 한다.