목차
· 객체의 메서드에서
· 프로토타입에서
· 이벤트 핸들러 함수에서
· 화살표 함수의 리팩토링
· 화살표 함수의 장점
· 화살표 함수의 단점
· 레퍼런스
JavaScript ECMAScript 6부터 도입된 화살표 함수(arrow function)은 function 키워드를 사용하여 함수를 정의하는 것보다 적은 타이핑을 요구하고 깔끔한 코드를 작성할 수 있으며, React 클래스 컴포넌트의 생성자에서 이벤트 핸들러 함수를 바인딩하지 않아도 된다는 장점이 존재한다.
자바스크립트에서 일반 함수는 함수를 선언할 때 this에 바인딩할 객체가 동적으로 결정된다. 즉, 함수를 호출할 때 함수가 어떻게 호출되었는지에 따라 this에 바인딩할 객체가 결정된다. 보통 자바스크립트에서 this가 가리키는 것은 전역객체인 window이다. 반면, 화살표 함수는 함수를 선언할 때 this에 바인딩 할 객체가 정적으로 결정된다. 일반 함수와 달리 언제나 상위 스코프의 this를 가리킨다. 이를 Lexical this 라고 한다.
객체의 메서드에서
let obj = {
test : "test",
myFunc : () => {
return this.test;
},
myTest : function() {
return this.test;
}
}
console.log(obj.myFunc()); // window.test를 의미하는 것이기 때문에 undefined
console.log(obj.myTest()); // test
위의 예제를 실행하면 myFunc() 메서드 본문에 작성된 this는 myFunc()을 호출한 obj가 아니라 JavaScript 객체인 window 객체를 호출한다. 따라서 myFunc() 메서드 본문의 this.test는 window.test인 꼴이며, window 객체에는 test 프로퍼티가 존재하지 않으므로 undefined가 반환된다. 그 밑에 myTest에 선언된 고전적인 자바스크립트 방식의 함수 선언식으로 지정된 myTest() 메서드를 확인해보면, obj에서 this를 원활하게 사용 할 수 있다.
프로토타입에서
프로토타입의 메서드를 정의하는 경우에도 동일한 규칙이 적용된다.
function obj() {
this.a = 10;
this.b = 20;
}
obj.prototype.sum = () => {
return this.a + this.b;
}
obj.prototype.sum2 = function() {
return this.a + this.b;
}
var firstObj = new obj();
console.log(firstObj.a); // 10
console.log(firstObj.b); // 20
console.log(firstObj.sum()); // NaN
console.log(firstObj.sum2()); // 30
위의 예제를 보았을 때, 항상 스코프 상위의 this를 가리키는 화살표 함수로 정의된 sum() 메서드의 this가 전역 객체인 window로 설정되었기 때문에 this.a + this.b는 NaN을 반환한다. 하지만, 화살표 함수가 아닌 고전적인 함수 선언식으로 선언된 sum2() 메서드를 정의하게 되면 a와 b의 값을 원활하게 가져오는 것을 확인할 수 있다.
이벤트 핸들러 함수에서
React와 같은 프레임워크가 등장하면서 이벤트 핸들러 함수를 등록하는 방법이 쉬워졌다. 기존에는 getElementById()와 같은 메서드를 이용하여 id에 addEventListener()과 같은 메세드를 통해 이벤트 핸들러 함수를 등록했다.
const button = document.getElementById('name');
button.addEventListener('click', () => {
this.innerHTML = "클릭"; // window.innerHTML을 의미
});
button.addEventListenter('click', function() {
this.innerHTML = "클릭"; // button.innerHTML을 의미
});
클릭 이벤트의 핸들러 함수를 화살표 함수로 정의하였으며, 해당 태그의 innerHTML을 변경하기 위해 this를 사용했다. 하지만 이벤트 핸들러 함수는 정상적으로 동작을 하지 않는다. 화살표 함수 본문에 정의된 this.innerHTML은 window.innerHTML과 동일하기 때문이다.
따라서 이벤트 핸들러 함수를 정상적으로 동작 시키기 위해 함수 선언식을 사용한다.
화살표 함수의 리팩토링
const cal = (util, num) => util === '+' ? num + 10 : util === '-' ? util - 10 : num;
console.log(cal('+', 100)); // 110
console.log(cal('-', 100)); // 90
console.log(cal('HI', 100)); // 100
화살표 함수는 중괄호와 return 문을 제거하여 코드를 간결하게 만들수 있지만, 지나친 리팩토링은 오히려 읽기 어려운 코드를 구현한다. 예를 들어 첫 번째 매개변수에 따라 두번째 매개변수에 10을 더하거나 10을 뺄셈하는 코드를 위의 코드와 같이 구현을 할 수 있다. 위의 코드는 문제없이 작동하지만, 제 3자의 입장에서 코드의 가독성을 오히려 해칠 수도 있다는 단점이 있다.
const cal = (util, num) => {
if (uill === '+') {
return num + 10;
} else if (util === '-') {
return num - 10;
} else {
return num;
}
}
console.log(cal('+', 100)); // 110
console.log(cal('-', 100)); // 90
console.log(cal('HI', 100)); // 100
화살표 함수를 통해 간결한 코드를 작성할 수 있지만, 간결함을 선택하고 가독성을 해칠 수도 있다는 점을 명심해두면 좋을 것 같다. 제 3자와의 개발 협업을 위해 가독성이 좋은 코드를 짤 수 있도록 습관을 들여놓는 것이 좋다.
화살표 함수의 장점
· 코드의 간결성
· 콜백 함수 this에 값을 참조시킬 때 (this 값에 lexical scope를 참조시킬 때)
· map 사용할 때 this를 넘겨주어 코드를 더 쉽게 작성할 수 있다.
화살표 함수의 단점
· function 키워드 또는 리터럴 방식으로 정의된 함수와 화살표 함수는 동일하게 작동하지 않는다.
레퍼런스
댓글