티스토리 뷰
🚀 들어가며...
- function 키워드를 생략하고 => 를 이용하여 함수를 훨씬 간단하게 표현할 수 있는 JavaScript의 화살표함수에 대해 알아보겠습니다.
- (ES6 이상부터 사용가능합니다.)
📑 내용
1. 화살표 함수의 기본 문법
- 기본표현식은 아래와 같습니다.
// 매개변수 지정 방법
() => { ... } // 매개변수가 없을 경우
x => { ... } // 매개변수가 한 개인 경우, 소괄호를 생략할 수 있습니다.
(x, y) => { ... } // 매개변수가 여러 개인 경우, 소괄호를 생략할 수 없습니다.
// 함수 몸체 지정 방법
x => { return x * x } // single line block
x => x * x // 함수 몸체가 한줄의 구문이라면 중괄호를 생략할 수 있으며 암묵적으로 return됩니다. 위 표현과 동일합니다.
() => { return { a: 1 }; }
() => ({ a: 1 }) // 위 표현과 동일합니다. 객체 반환시 소괄호를 사용합니다.
() => { // multi line block.
const x = 10;
return x * x;
};
위에 소스만 보아도 화살표 함수가 얼마나 편리하고 강력한지 짐작이 가실것 같습니다.
ES5 문법일때와 비교해볼까요??
// ES5
var pow = function (x) { return x * x; };
console.log(pow(10)); // 100
// ES6
const pow = x => x * x;
console.log(pow(10)); // 100
더 직관적이고, 소스길이가 짧아졌습니다.
2. 기본적으로 화살표함수는 익명 함수로만 사용할 수 있기 때문에, 함수를 호출하기 위해서는 표현식으로 써야합니다.
화살표함수는 항상 익명임을 아셔야합니다.
(익명함수: 함수를 재사용하지 않을 목적으로 함수에 이름을 붙이지 않는 것)
또한 일반함수보다 간결하게 콜백함수로 사용될 수 있습니다.
(ex)
var numbers = [1, 2, 3, 4, 5];
var newArray = numbers.map(a => a + a);
console.log(newArray); //[2, 4, 6, 8, 10]
3. 화살표함수와 this
함수가 어떻게 호출되었는지에 따라 바인딩할 객체가 결정되는 일반함수와는 달리, 화살표함수의 this는 화살표함수가 호출되는 시점과는 무관하게 선언되는 시점에 결정되며 언제나 상위 스코프의 this를 가리킵니다.
왜냐하면,
화살표함수에는 this와 argument가 없기 때문입니다.
그래서 일반적으로 this가 개입되는 경우라면 일반함수를 사용합니다.
예를 들어 알아보겠습니다.
let obj = {
myName: 'Son',
logName: function() {
console.log(this.myName);
}
};
obj.logName(); //"son"
//콜백함수로 일반함수표현방식을 사용하면 dot notation법칙에 따라 this는 obj객체가 됩니다.
만일 위 예제를 화살표함수로 표현할 경우, this를 사용할수 있을까요?
var obj = {
myName: 'Son',
logName: () => {
console.log(this.myName);
}
};
obj.logName(); //undefined
/*콜백함수로 화살표함수를 사용하면 이 예제의 경우 this는 상위 스코프인 전역스코프 혹은
window객체가 됩니다.
현재 상위 스코프에는 변수 myName이 존재하지 않으므로 undefined를 반환합니다.*/
따라서 정답은 X 입니다.
window객체에 myName의 값을 할당해주면 아래와 같은 결과를 얻게 된다.
그렇다면 만일 화살표함수에서도 this를 사용해주려면 어떻게해야할까요??
window.myName = "Son";
var obj = {
myName: 'Son',
logName: () => {
console.log(this.myName);
}
};
obj.logName(); //"Son"
//여기서 this는 obj객체의 상위스코프의 this인 window객체가 됩니다.
이런식으로 위에 window객체로 선언해주시면 사용가능합니다.
컴포넌트형 같은경우에는 constructor 안에 this.변수명 으로 선언된 변수가 있다면, 화살표 함수 안에서 this.변수명 으로 사용가능합니다.
화살표함수의 this 바인딩 객체 결정방식은 렉시컬 스코프(Lexical Scope)와 유사합니다.
- 렉시컬 스코프(Lexical Scope): 함수를 어디서 선언하였는지에 따라 상위 스코프가 정해지는 방식. 자바스크립트를 비롯한 대부분의 프로그래밍 언어는 렉시컬 스코프를 따릅니다. ↔ 동적 스코프(Dynamic Scope)
화살표 함수에서 this를 사용할 경우 일반 변수와 동일하게 스코프 체인을 따라 탐색하게 됩니다.
4. 화살표함수를 사용할 수 없는 경우
화살표함수를 사용할 수 없는경우도 존재합니다.
4-1 method
화살표 함수로 메소드를 정의하는 것은 피해야 합니다. 예로 알아보겠습니다.
// 나쁜 예
const introduce = {
name: 'Son',
sayName: () => console.log(`Hi ${this.name}`)
};
introduce.sayName(); // Hi undefined
// 좋은 예 (ES6 축약 메소드 표현 사용)
const introduce = {
name: 'Son',
sayName() {
console.log(`Hi ${this.name}`)
}
};
introduce.sayName(); // Hi Son
위 예제의 경우, 메소드로 정의한 화살표 함수 내부의 this는 메소드를 소유한 객체, 즉 메소드를 호출한 객체를 가리키지 않고 상위 컨택스트인 전역 객체 window를 가리킵니다. 따라서 화살표 함수로 메소드를 정의하는 것은 바람직하지 않습니다.
이와 같은 경우는 메소드를 위한 단축 표기법인 ES6 축약 메소드 표현을 사용하는 것이 좋습니다.
4-2 prototype
화살표 함수로 정의된 메소드를 prototype에 할당하는 경우도 동일한 문제가 발생합니다.
// 나쁜 예
const introduce = {
name: 'Son',
};
Object.prototype.sayHi = () => console.log(`Hi ${this.name}`);
person.sayHi(); // Hi undefined
// 좋은 예
const introduce = {
name: 'Son',
};
Object.prototype.sayHi = function() {
console.log(`Hi ${this.name}`);
};
person.sayHi(); // Hi Son
화살표 함수로 객체의 메소드를 정의하였을 때와 같은, 즉 생성자 함수를 호출한 Instance를 가리키지 않고 상위 컨택스트인 전역 객체를 가리킵니다. 따라서 prototype에 메소드를 할당하는 경우, 일반 함수를 할당해야 합니다.
4-3 생성자함수
화살표 함수는 생성자 함수로 사용할 수 없습니다. 생성자 함수는 prototype 프로퍼티를 가지며 prototype 프로퍼티가 가리키는 프로토타입 객체의 constructor를 사용합니다. 하지만 화살표 함수는 prototype 프로퍼티를 가지고 있지 않습니다.
const Son = () => {};
// 화살표 함수는 prototype 프로퍼티가 없습니다.
console.log(Son.hasOwnProperty('prototype')); // false
const foo = new Son(); // TypeError: Son is not a constructor
4-4 addEventListener 함수의 콜백 함수
addEventListener 함수의 콜백 함수를 화살표 함수로 정의하면 this가 상위 컨택스트인 전역 객체 window를 가리킵니다.
// 나쁜 예
var button = document.getElementById('myButton');
button.addEventListener('click', () => {
console.log(this === window); // => true
this.innerHTML = 'Clicked button';
});
// 좋은 예
var button = document.getElementById('myButton');
button.addEventListener('click', function() {
console.log(this === button); // => true
this.innerHTML = 'Clicked button';
});
따라서 addEventListener 함수의 콜백 함수 내에서 this를 사용하는 경우, function 키워드로 정의한 일반 함수를 사용하여야 합니다. 일반 함수로 정의된 addEventListener 함수의 콜백 함수 내부의 this는 이벤트 리스너에 바인딩된 요소(currentTarget)를 가리킵니다.
🙋🏻♂️ 후기
화살표 함수는 정말 유용하지만, 그 특징을 제대로 알고 써야만 오류없이 효과적으로 사용이 가능합니다. 써야할때는 제대로 사용하고, 사용하면 안될때를 구분하여 사용하면 javascript다운 코드를 완성할 수 있으실 것 같습니다.
이번 포스팅을 진행하다보니 this라는 키워드에 대해 더 공부해야 겠다는 것을 느꼈습니다.
다음에는 this라는 키워드에 대해 좀 더 자세히 공부하여 포스팅 하도록 하겠습니다!
🔗 참고한 글
https://poiemaweb.com/es6-arrow-function
'JavaScript' 카테고리의 다른 글
[JavaScript] default export와 named export의 차이점을 알아보자! (0) | 2022.07.28 |
---|---|
[JavaScript] this에 대해 알아보자! (0) | 2022.06.21 |
[JavaScript] 소수점 계산오류 해결하기 (1) | 2022.05.17 |
- Total
- Today
- Yesterday
- static files
- Algorithm
- list
- Python
- PostgreSQL
- django
- django ORM
- container
- data formatting
- lv1
- JS
- SQL
- generator expression
- uSWGI
- Master & Slave
- This
- lv2
- MVT
- Default export
- Greedy Algorithm
- 탐욕법
- react
- JavaScript
- union-find
- docker
- programmers
- ORM
- db
- Linux
- Named export
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |