* 화살표 함수 (Arrow function)
[참조 내용] https://latte1114.tistory.com/367
* 예시 코드
// arrow function
const user = {
name : 'Hyeonwoo',
getName : () => {
return this.name;
},
};
user.getName(); // undefined
// 일반 method
const user = {
name : 'Hyeonwoo',
getName() {
return this.name;
},
};
user.getName(); // Hyeonwoo
- 화살표 함수로 this.name에 접근시 undefined가 반환된다.
- 일반 메서드로 this.name에 접근시 정상적으로 this.name의 값이 반환된다.
- JavaScript의 arrow function을 메서드에 사용할 경우 이러한 문제가 발생할 수 있다.
* 이유는 ??
화살표 함수는 Scope를 Lexical scope를 가지게된다. 이 Lexical scope를 가지게 되면 여기서 호출된
this를 바라보는게 아닌 그저 Lexical scope로 바로 상위의 문맥을 따르는 경우가 있다.
따라서 상위의 문맥을 따르고 기존의 this의 동작방식을 따르지 않기 때문에 화살표 함수를 사용하게 되면
위와 같이 this를 사용하였을때 값을 찾지 못하고 undefined가 반환된다.
따라서 메서드에서 화살표 함수를 사용할 때 이러한 this조작법을 주의해야한다.
* 또한 arrow function을 사용하게 되면 arguments객체를 사용할 수 없다.
const user = {
name : 'Hyeonwoo',
getName : () => {
return this.name;
},
newFriends : () => {
const newFriendList = Array.from(arguments);
return this.name + newFriendList;
},
};
user.getName(); // undefined
console.log(user.newFriends('latte')); // ReferenceError: arguments is not defined
- call, apply, bind도 사용할 수 없다.
- 그 외에도 내부에서 많은것을 사용할 수 없다.
- 화살표 함수는 일반적인 자바스크립트의 함수가 가지고 있는 모든것을 그대로 계승해서 가지고 있지는 않다.
* 그렇다면 arguments객체 사용 해결 방법은??
- arguments대신 rest parameter를 사용하면 된다.
const user = {
name : 'Hyeonwoo',
getName : () => {
return this.name;
},
newFriends : (...rest) => {
return this.name + rest
},
};
user.getName(); // undefined
console.log(user.newFriends('latte')); // latte
* 만약 생성자 함수를 만들어서 new연산자와 더해서 무언가 instance를 만들려고한다.
- 화살표 함수로 만든 함수는 생성자로 사용할 수 없다. (매우 큰 단점)
- 하지만 요즘은 Class가 있다 !!
const Person = (name, city) => {
this.name = name;
this.city = city;
};
const person = new Person('hyeonwoo', 'korea');
* Class를 다룰 때 주의해야할 부분
- arrow function으로 만든 부모 메서드를 호출하면 error가 발생한다.
- arrow function은 class에서 구현하였을때 생성자 함수 내부에서 바로 초기화가 되버리는 현상이 있다.
- 따라서 arrow function으로 만드는 this와 class내부의 메서드는 이러한 문제점을 자주 만들어 낸다.
* 추가적인 문제점이 하나 더 있다. (arrow function을 사용시)
- 만약 Child라는 class에서 Parent의 메서드들을 overriding받은뒤에
부모에 있는 메서드와 동일한 이름의 메서드를 선언하여서 호출하면 부모의 메서드가 호출된다.
(해당 부분은 오류를 만들어 낼 수 있으니 유의할것)
// 부모 class
class Parent {
parentMethod() {
console.log('parentMethod');
}
// error 발생(BAD)
parentMethodArrow = () => {
console.log('parentMethodArrow');
};
overrideMethod = () => {
return 'Parent';
};
}
// 자식 class
class Child extends Parent {
childMethod() {
super.parentMethodArrow();
}
overrideMethod() {
return 'Child';
}
}
new Child().childMethod();
new Child().overrideMethod(); // Parent; (부모의 메서드가 호출됨 BAD)
* 해결방법은??
- 일반적인 메서드로 바꿔주면 된다.
// 부모 class
class Parent {
parentMethod() {
console.log('parentMethod');
}
parentMethodArrow() {
console.log('parentMethodArrow');
};
overrideMethod () {
return 'Parent';
};
}
// 자식 class
class Child extends Parent {
childMethod() {
super.parentMethodArrow();
}
overrideMethod() {
return 'Child';
}
}
new Child().childMethod();
console.log(new Child().overrideMethod()); // Child; (정상적으로 자식의 메서드의 값이 호출 GOOD)
[결론적으로]
리액트에서는 화살표함수로 메서드를 만드는게 당연하기 때문에 JS에서 Class를 만들때도 습관처럼 화살표함수를 사용하게 된다. 리액트가 아닌 JS에서는 큰 문제가 발생할 수 있기때문에 유의해야한다.
(맹목적으로 화살표함수를 사용하지 말것)
화살표 함수를 적극적으로 활용하더라도 뭐가 문제인지는 파악해야한다.
'Study > JavaScript(Clean code)' 카테고리의 다른 글
[JavaScript][clean-code] 순수 함수(pure function) (2) | 2022.06.15 |
---|---|
[JavaScript][clean-code] Callback Function (0) | 2022.06.15 |
[JavaScript][clean-code] void & return (0) | 2022.06.13 |
[JavaScript][clean-code] Rest Parameters (0) | 2022.06.13 |
[JavaScript][clean-code] default Value / default parameter (0) | 2022.06.12 |