JavaScript - 화살표 함수 표현식

dobby·2024년 11월 29일
0
post-thumbnail

화살표 함수

화살표 함수를 표현할 수 있는 방식

  • 매개변수 표현
    매개변수가 하나뿐이면, 매개변수의 괄호 부분을 생략할 수 있다.
    // 매개변수가 없을 경우
    () => { ... }

// 매개변수가 한 개인 경우, 소괄호를 생략할 수 있다.
x => { ... }

// 매개변수가 여러 개인 경우, 소괄호를 생략할 수 없다.
(x, y) => { ... }

- 함수 몸체 표현
함수 몸체 내의 코드가 한 줄이고, 단순히 return 문 밖에 없다면 중괄호와 return 키워드를 생략할 수 있다.
```javascript
x => { return x * x };

// 함수 몸체가 한 줄의 구문이라면, 중괄호를 생략할 수 있으며 암묵적으로 return된다.
// 위 표현과 동일하다
x => x * x;
  • 객체 리터럴 반환
    객체 리터럴을 반환하려면 소괄호로 감싸야 한다.
    중괄호만 쓰면, 함수 블록인지 객체 블록인지 판단할 수 없기 때문이다.
    () => { return { a:1}; }
    // 위 표현과 동일, 객체 반환시 소괄호를 사용한다.
    () => ({a:1});

화살표 함수 특징

자바스크립트의 화살표 함수는 function 함수를 축약하여 표현하는 문법이지만, 일반적인 함수와 다른 몇 가지 고유한 특징을 가진다.

이러한 특징은 화살표 함수를 유용하게 만들기도 하지만, 함정이 되기도 하기 때문에 유의깊게 살펴보아야 한다.


📌 화살표 함수엔 this가 없다.

화살표 함수에는 this가 존재하지 않는다.
그래서 화살표 함수에서 this 키워드로 접근하면, 자신이 아닌 상위 환경에서 값을 가져오게 된다.

화살표 함수는 자신만의 this를 가지지 않기 때문에, 자신을 감싸는 상위 환경의 this를 그대로 따르기 때문이다.
즉, 화살표 함수에서 this는 정적으로 결정된다.

예를 들어 user라는 객체의 sayHi의 프로퍼티가 어떠한 형태의 함수로 이루어져 있느냐에 따라 this.name이 가리키는 값이 달라지게 된다.

let name = "Global";

let user = {
 name: 'dobby',
 sayHi: function() {
  console.log(this.name); 
 }
};

user.sayHi(); // dobby

let user = {
 name: 'dobby',
 sayHi: () => {
  console.log(this.name); 
 }
};

user.sayHi(); // Global

화살표 함수는 함수가 선언된 시점의 상위 스코프에서 this를 찾는다.


📌 화살표 함수엔 arguments가 없다.

자바스크립트 함수의 arguments는 일반적으로 함수가 호출될 때 전달된 인수들을 담고 있는 유사 배열 객체이다.

function argsFunc() {
 console.log(arguments); 
}
argsFunc(1, 2, 3); // [1, 2, 3]

화살표 함수는 일반 함수와는 다르게, 모든 인수에 접근할 수 있게 해주는 유사 배열 객체인 arguments를 지원하지 않는다.
따라서 실행하면 다음과 같이 에러가 발생하게 된다.

const argFunc = () => {
  console.log(arguments);
}
argsFunc(1,2,3); // Error

대신에, 나머지 매개변수라는 문법을 사용하여 인수들을 배열로 받을 수 있다.

const argsFunc = (...args) => {
 console.log(args); 
}
argsFunc(1,2,4); // [1,2,3]

📌 화살표 함수는 생성자 함수가 없다.

생성자 함수란 new 연산자와 함께 호출되어 객체를 생성하는 함수를 말한다.

function User(name) {
 this.name = name; 
}

const user = new User('dobby');
console.log(user.name); // dobby

화살표 함수는 this가 없기 때문에 new와 함께 실행할 수 없다.
따라서 화살표 함수는 new와 함께 호출할 수 없다.

화살표 함수는 객체를 생성하는 용도로 사용할 수 없으며, 보통 콜백 함수나 익명 함수로서 사용되는 편이다.


📌 화살표 함수를 남용해서는 안되는 경우

화살표 함수는 일반 함수와는 달리 자신만의 this를 가지지 않는다.
그래서 화살표 함수를 자바스크립트에서 사용함에 있어 몇 가지 제약이 생긴다.


일반 객체의 메소드 사용 X

만일 this 참조를 자주 사용해야할 메소드 로직이라면, 일반 객체의 메소드로서 화살표 함수 사용은 피해야 한다.

왜냐하면, this가 없으니 메소드를 호출한 객체를 가리키지 않고 상위 컨텍스트인 전역 객체 window를 가리키게 되기 때문이다.


prototype 메소드로 사용 X

화살표 함수로 정의된 메소드를 prototype 객체로서 할당하는 경우도 위와 같은 동일한 문제가 발생한다.
따라서 prototype에 메소드를 할당하는 경우, 일반 함수를 할당하도록 한다.

const person = {
  name: 'dobby',
}
Object.prototype.sayHi = () =>. console.log(`Hi ${this.name}`);
// 모든 객체는 기본적으로 Object 객체에 프로토타입 체이닝 되어있다.
person.sayHi(); // Hi undefined


생성자 함수로 사용 X

생성자 함수는 prototype 프로퍼티를 가지며, prototype 프로퍼티가 가리키는 Prototype Objectconstructor를 사용한다.
하지만, 화살표 함수는 prototype 프로퍼티를 가지고 있지 않기 때문에 위와 같은 이유로 사용하면 안된다.

const Foo = (name) => {
 this.name = name; 
}
console.log(Foo.hasOwnProperty('prototype')); // false
const foo = new Foo('FFF'); // TypeError


📌 addEventListener의 콜백 함수는 조심해서 사용

화살표 함수를 addEventListener 함수의 콜백 함수로 사용할 때도 주의해야 한다.
addEventListner 함수는 이벤트가 발생할 때마다 콜백 함수를 호출하는데, 이때 콜백 함수의 this는 이벤트가 발생한 요소를 가리키게 된다.

<button>Click me!</button>

<script>
let button = document.querySelector('button');

button.addEventListener('click', function() {
  console.log(this); // <button> 요소
});
</script>

하지만 화살표 함수를 콜백 함수로 사용하면, this는 외부 렉시컬 환경의 this를 가리키게 되므로, 원하는 결과가 나오지 않을 수 있다.

<button>Click me!</button>

<script>
let button = document.querySelector('button');

button.addEventListener('click', () => {
  console.log(this); // window 객체
});
</script>

따라서 addEventListenr 함수 내에서 this 키워드를 사용하는 경우엔, 화살표 함수 대신 일반적인 함수를 사용하는 것이 올바르다.
하지만, 현업에서는 forEach와 더불어 addEventListener 함수의 콜백 함수를 코드 표현의 간략화를 위해 화살표 함수를 쓰는 사례가 많다.

따라서 이런 경우에는 this 키워드를 사용하지 말고, addEventListener 함수의 매개변수인 event 객체의 currentTarget 혹은 target 프로퍼티를 사용하여 이벤트가 발생한 요소에 접근하는 편이다.

<button>Click me!</button>

<script>
let button = document.querySelector('button');

button.addEventListener('click', (event) => {
  console.log(event.target); // <button> 요소
});
</script>

📌 call, apply, bind로 this를 변경할 수 없다.

보통 자바스크립트에서 this 키워드를 조작하는 대표적인 방법으로,
call, apply, bind 함수를 이용한 기법이 있다.
이는 화살표 함수에는 통하지 않는다.
간단하게, 화살표 함수는 this 자체가 없기 때문이다.

const obj1 = { message: 'Hello from obj1' };
const obj2 = { message: 'Hello from obj2' };

// 일반 함수
function normalFunction() {
  console.log(this.message);
}

// 화살표 함수
const arrowFunction = () => {
  console.log(this.message);
};

// 일반 함수에서 this 변경
normalFunction.call(obj1); // 'Hello from obj1'
normalFunction.call(obj2); // 'Hello from obj2'

// 화살표 함수에서 this 변경 (변경이 되지 않음)
arrowFunction.call(obj1); // undefined
arrowFunction.call(obj2); // undefined

이처럼 화살표 함수는 ES6에서 도입된 새로운 방식으로, 간단하고 간결한 문법으로 유연한 표현력을 높여주는 함수를 만들 수 있지만, 모든 상황에 화살표 함수를 사용할 수 있는 것은 아니므로, 주의해야할 점도 있다.

profile
성장통을 겪고 있습니다.

0개의 댓글