모래블로그

[JavaScript] Arrow Function vs Function 본문

Language/JavaScript

[JavaScript] Arrow Function vs Function

별모래 2024. 2. 14. 13:58
728x90

화살표 함수 (Arrow Function)

ES6 문법인 화살표 함수(Arrow Function)는 function 키워드 대신 화살표(=>)를 사용하여 간단하게 함수를 표현할 수 있다.

그렇다고 모든 경우 화살표 함수를 사용할 수 있는 것은 아니다.

1.  화살표 함수 기본 문법

// 매개변수 지정 방법
    () => { ... } // 매개변수가 없을 경우
     a => { ... } // 매개변수가 한 개인 경우, 소괄호 생략 가능
 (a,b) => { ... } // 매개변수가 여러 개인 경우, 소괄호 생략 x
// 객체 반환 시
() => ({ a : 1, b : 2 }) // 객체를 반환할 때는 소괄호를 사용

 

2.  화살표 함수의 호출

화살표함수는 익명함수로만 사용할 수 있다. 따라서 함수를 호출하기 위해서는 함수 표현식을 사용한다.

// ES5 일반 함수
var a = function (x) {
	return x * x;
}
// ES6 화살표 함수
var b = x => x * x;

 

3. 함수와 화살표 함수의 차이점

this, arguments, super 또는 new.target을 바인딩하지 않는다.

 

1. 화살표 함수는  this를 가지지 않는다.

화살표 함수는 this를 가지지 않으므로 내부에서 this를 사용하면 자신 밖의 this를 사용하게 된다.

 

2. 화살표 함수에는  arguments가 없다.

arguments는 함수의 인자를 배열처럼 사용할 수 있도록 제공되는 객체이다. 화살표 함수에서는 이게 없다.

 

3. 화살표 함수는 new와 함께 호출할 수 없다.

일반 함수는  new 연산자를 이용해서 객체로 만들 수 있는데 화살표 함수는 this가 없으므로  new를 사용할 수 없다.

 

4. 화살표 함수에는 super가 없다.

super는 클래스 상속에 관련된 객체이다. this가 없어 new를 쓰지 못하므로 super도 없다.


4. this

function 키워드로 생성한 일반 함수와 화살표 함수의 가장 큰 차이점은 this 이다.

 

3-1. 일반 함수의  this

자바스크립트의 경우, 함수 호출 방식에 의해 this 에 바인딩할 어떤 객체가 동적으로 결정된다.

즉, 함수를 선언할 때 this에 바인딩할 객체가 정적으로 결정되는 것이 아니라 함수를 호출할 때 함수가 어떻게 호출되었는지에 따라 this에 바인딩할 객체가 동적으로 결정된다.

콜백 함수 내부의 this는 전역 객체 window를 가리킨다.

 

3-2. 화살표 함수의 this

화살표 함수는 함수를 선언할 때 this에 바인딩할 객체가 정적으로 결정된다.

일반 함수와는 달리, 화살표함수의 this는 언제나 상위 스코프의 this를 가리키며, 이를 Lexical this라고 한다.

this를 클로저 값으로 처리하는 것과 같다.

function Prefixer(prefix) {
  this.prefix = prefix;
}

Prefixer.prototype.prefixArray = function (arr) {
  // this는 상위 스코프인 prefixArray 메소드 내의 this를 가리킨다.
  return arr.map(x => `${this.prefix}  ${x}`);
};

const pre = new Prefixer('Hi');
console.log(pre.prefixArray(['Park', 'Lee']));

 

화살표 함수는  call, apply, bind 메소드를 사용하여 this를 변경할 수 없다.

window.x = 1;
const normal = function () { return this.x; };
const arrow = () => this.x;

console.log(normal.call({ x: 10 })); // 10
console.log(arrow.call({ x: 10 }));  // 1

 

4.  화살표 함수를 사용해서는 안되는 경우

4-1. 메소드(Method)

화살표 함수로 메소드를 정의하는 것은 피해야 한다.

// Bad
const person = {
	name = 'Park',
    sayHi : () => console.log(`Hi ${this.name}`)
}

person.sayHi(); // Hi undefined


// Good
const person = {
	name = 'Park',
    sayHi() { // === sayHi: function() {
    	console.log(`Hi ${this.name}`);
    }
}

person.sayHi(); // Hi Park

 

메소드로 정의한 화살표 함수 내부의 this는 메소드를 소유한 객체, 즉 메소드를 호출한 객체를 가리키지 않고 상위 컨텍스트인 전역 객체 window를 가리킨다.

 

4-2. 프로토타입(Prototype)

화살표함수로 정의된 메소드를 prototype에 할당하는 경우도 동일한 문제가 발생한다.

 

// Bad
const person = {
	name = 'Park',
}

Object.prototype.sayHi = () => console.log(`Hi ${this.name}`);

person.sayHi(); // Hi undefined


// Good
const person = {
	name = 'Park',
}
Object.prototype.sayHi = function() {
    console.log(`Hi ${this.name}`);
}

person.sayHi(); // Hi Park

 

4-3. 생성자 함수(consturctor)

화살표 함수는 생성자 함수로 사용할 수 없다.

생성자 함수의 경우는 prototype 프로퍼티를 가지며, prototype 프로퍼티가 가리키는 프로토타입 객체의 constructor를 사용한다.

그러나 화살표 함수는 prototype 프로퍼티를 가지고 있지 않다.

 

const a = () => {}

// 화살표 함수는 prototype 프로퍼티가 없다
console.log(a.hasOwnProperty('prototype')); // false

const b = new a(); // TypeError : a is not a constructor

 

4-4. addEventListener 함수의 콜백 함수 (내부에서 this를 사용하는 경우)

 

addEventListener 함수의 콜백 함수를 화살표 함수로 정의하면 this가 상위 컨텍스트인 전역 객체 window를 가리킨다.

// Bad
var button = document.getElementById('myButton');

button.addEventListener('click', () => {
  console.log(this === window); // true
  this.innerHTML = 'Clicked button';
})


// Good
var button = document.getElementById('myButton');

button.addEventListener('click', function() {
  console.log(this === button); // true
  this.innerHTML = 'Clicked button';
})

 

따라서 addEventListener 함수의 콜백 함수 내에서 this를 사용하는 경우, function 키워드로 정의한 일반 함수를 사용하여야 한다.

일반 함수로 정의된 addEventListener 함수의 콜백 함수 내부의 this는 이벤트 리스너에 바인딩된 요소(currentTarget)를 가리킨다.

 


참조🙇‍♀️

https://poiemaweb.com/es6-arrow-function

https://sewonzzang.tistory.com/21

https://velog.io/@modolee/javascript-function-vs-arrow-function

https://offbyone.tistory.com/465

728x90

'Language > JavaScript' 카테고리의 다른 글

[JavaScript] 구조 분해 할당  (0) 2024.02.14
[JavaScript] Spread Operator(스프레드 연산자)  (0) 2024.02.14
[JavaScript] 일급객체  (0) 2024.02.07
[JavaScript] 호이스팅이란  (0) 2024.01.19
[JavaScript] 스코프(scope)  (0) 2024.01.19