When ‘not’ to use arrow function
아래의 내용은 http://rainsoft.io/when-not-to-use-arrow-functions-in-javascript/ 를 바탕으로 arrow function을 사용 시 주의 하기위해 번역을 한 내용입니다.향후 원문의 블로그 사용자의 요청으로 문제가 생긴다면 포스트 한것을 지우도록 하겠습니다.또한 sns에는 공유는 하지 않았습니다. 이점 확인 하시고 절대 따로 복사하여 배포는 하지 않으셨으면 합니다.
ECMAScript 6(ECMA2015)에서 표준으로 정해진 arrow function을 사용하지 말아야 하거나 또는 사용하면 가독성이 떨어지는 몇가지 예를 알아 보도록 하자
아래의 소스 코드와 같이 Object literal 방식에서 property를 함수 형태로 정의 시 arrow function으로 정의 하기데 되면 arrow function의 this가 해당 Object가 아닌 window가 되어 원하는 결과가 나오지 않을 수 있다.
var calculate = { array: [1, 2, 3], sum: () => { console.log(this === window); // => true return this.array.reduce((result, item) => result + item); } }; console.log(this === window); // => true // Throws "TypeError: Cannot read property 'reduce' of undefined" calculate.sum();
위의 소스코드를 보면 this와 window는 같다는 결과가 나왔으며, calculate.sum()은 TypeError를 발생한다.위와 같은 것은 function expression 또는 shorthand syntax를 사용하여 해결을 할수 있다.
var calculate = { array: [1, 2, 3], sum() { console.log(this === calculate); // => true return this.array.reduce((result, item) => result + item); } }; calculate.sum(); // => 6
위와 같이 calculate와 this는 같은 것을 되어 calculate.sum()는 원하는 결과를 얻게 된다.
Object의 prototype과 같은 경우에도 발생을 한다. 아래와 같이 arrow function을 사용하며 this는 window와 같게 되며, 월하는 결과를 얻지 못하게 된다.
function MyCat(name) { this.catName = name; } MyCat.prototype.sayCatName = () => { console.log(this === window); // => true return this.catName; }; var cat = new MyCat('Mew'); cat.sayCatName(); // => undefined
위와 같은 소스코드는 shorthand syntax로는 수정이 불가능 하며, function expression(함수표현식)으로 수정하면 된다.
function MyCat(name) { this.catName = name; } MyCat.prototype.sayCatName = function() { console.log(this === cat); // => true return this.catName; }; var cat = new MyCat('Mew'); cat.sayCatName(); // => 'Mew'
2. Callback functions with dynamic context
arrow function은 dynamic context인 경우에도 사용이 불가능 하다. this로 인해 객체에 접근이 안되기 때문이다. 아래와 소스코드는 이벤트가 발생할때 실행하는 callback function를 arrow function으로 작성을 했다. 이렇게 되면 this가 이벤트를 발생시킨 타켓이 되지 않기 때문에 이벤트 발생시 함수가 제대로 실행이 되지 않는다.
var button = document.getElementById('myButton'); button.addEventListener('click', () => { console.log(this === window); // => true this.innerHTML = 'Clicked button'; });
이것은 아래와 같이 function expression(함수표현식)으로 변경하여야 실행이되고 this도 이벤트를 발생시킨 target이 된다.
var button = document.getElementById('myButton'); button.addEventListener('click', function() { console.log(this === button); // => true this.innerHTML = 'Clicked button'; });
생성자 함수에서도 arrow function 은 typeError를 발생한다. 소스코드를 보면 TypeError가 발생된다.
var Message = (text) => { this.text = text; }; // Throws "TypeError: Message is not a constructor" var helloMessage = new Message('Hello World!');
이것을 해결하기 위하서는 function expression을 사용하여 해결 할 수 있다.
var Message = function(text) { this.text = text; }; var helloMessage = new Message('Hello World!'); console.log(helloMessage.text); // => 'Hello World!'
마지막으로 너무 많은 arrow function의 사용으로 가독성이 떨어지는 경우이다.아래의 소스코드는 심플하고 간단하지만 이해하는데 약간의 시간이 걸린다.그것은 curly braces으로 작성되었다.
let multiply = (a, b) => b === undefined ? b => a * b : a * b; let double = multiply(2); double(3); // => 6 multiply(2, 3); // => 6
이러한 경우는 심플한 것 보다 협업을 위해 코드를 이해하기 쉽도록 변경하는 것이 좋다.
function multiply(a, b) { if (b === undefined) { return function(b) { return a * b; } } return a * b; } let double = multiply(2); double(3); // => 6 multiply(2, 3); // => 6
위의 소스코드는 장황하고 짧은 소스코드를 균형이 맞게 수정한 것이다.
arrow function은 의심할 여지가 없이 좋은 것이다. arrow fuction 단순하면서도 정확한 곳에 가져다 써야 한다. 몇몇 상황의 이익은 다른 곳에 불이익을 가져다 준다. 위에 언급한 곳에서는 arrow function을 사용하지 말아야 한다.