자바스크립트 화살표 함수

jisoung·2022년 9월 19일

화살표 함수

ES6에서 뚱뚱한 화살표(⇒)를 사용해서 함수를 선언하는 방법인 화살표 함수가 처음 도입되었다. ES5에서 일반적으로 함수를 선언하는 방법은 다음과 같았다.

const greeting = function(name){
	return "hello" + name;
};

이는 화살표 함수 문법으로 바꾸면 다음과 같다

var greeting = (name) => {
	return "hello" + name;
};

매개변수가 하나만 있으면 괄호를 생략하고 다음과 같이 쓸 수도 있다.

var greeting = name => {
	return "hello" + name;
};

매개변수가 젼혀 없으면 다음과 같이 빈 괄호를 써야 한다.

var greeting = () => {
	return "hello";
};

암시적 반환

화살표 함수를 사용하면 명시적인 반환을 생략하고 다음과 같이 반환할 수 있다.

const greeting = name => `hello ${name}`;

ES5의 함수와 나란히 비교해보자.

const oldFunction = function(name){
	return "hello" + name;
};

const arrowFunction = name => `hello ${name}`;

두 함수 모두 결과는 같지만, 새로 도입된 문법을 사용하면 코드가 더 간결해진다.

하지만 주의하자! 코드의 간결함보다 더 중요한 것은 가독성이다. 팀 단위의 프로젝트에서 모든 팀원이 ES6의 문법을 숙지하지는 못했다면, 함수를 다음과 같이 작성하는 것이 좋다.

const arrowFunction = (name) => {
	return `hello ${name}`;
};

객체 리터럴을 암시적으로 반환해야 한다면, 다음과 같은 코드를 사용할 수 있다.

const race = "100m dash";
const runners = ["Uusain Bolt", "Justin Gatlin", "Asafa Powell"];

const results = runners.map((runner, i) => ({
	name: runner,
	race, // race : race
	place: i + 1
}));

cosole.log(results);
// [{name: "Usain Bolt", race: "100m dash", place: 1}]
// [{name: "Justin Gatlin", race: "100m dash", place: 2}]
// [{name: "Asafa Powell", race: "100m dash", place: 3}]

이 예에서는 map 함수를 사용하여 runners 배열에 대한 반복(순회)을 구현 한다. 첫 번째 인수는 runner는 배열의 현재 원소고, i는 배열의 인텍스(index)다. 배열의 각 원소에 대해 name, race, place 속성을 포함하는 객체를 results에 추가한다.

중괄호 안에 있는 것이 암시적으로 반환하려는 객체 리터럴임을 자바스크립트에 알리려면, 전체를 괄호 안에 감싸야 한다.

여기서 race를 쓰나 race: race를 쓰나 모두 결과는 모두 동일하다.

화살표 함수는 익명 함수

이전 예제에서 볼 수 있듯이 화살표 함수는 익명 함수이다.

참조할 이름이 필요하다면 함수를 변수에 할당하면 된다.

const greeting = name => `hello ${name}`;
greeting("Tom");

화살표 함수와 this 키워드

화살표 함수 내부에서 this 키워드를 사용할 때는 일반 함수와 다르게 동작하므로 주의해야 한다.

화살표 함수를 사용할 때 this 키워드를 상위 스코프에서 상속된다.

이런 특성을 다음과 같은 경우에 유용하게 쓸 수 있다.

<div class="box open">
	This is a box
</div>
.opening{
	background-color: "red";
}
// box 클레스를 가진 div를 가져온다.
const box = document.querySelector('.box');
// click 이벤트를 핸들러를 등록
box.addEventListener('click', function(){
	// div에 opening 클레스를 토글
	this.classList.togle("opening");
	setTimeOut(function(){
		// 클레스를 다시 토글
		this.classList.toggle("opening");
	},500);
});

이 코드의 문제는 , 첫 번째 this가 const box에 할당되었지만 setTimeOut 내부의 두 번째 this는 window 객체로 설정되어 다음과 같은 오류가 발생한다는 점이다.

// Uncaught TypeError: cannot read property "toggle" of undefined

화살표 함수가 부모 스코프에서 this의 값을 상속한다는 것을 인지하면, 다음과 같이 함수를 다시 작성할 수 있다.

const box = document.querySelector(".box");
// click 이벤트 핸들러를 등록
box.addEventListener("click", function(){
	// div에 opening 클래스를 토글
	this.classList.toggle("opening");
	setTimeOut(()=>{
		// 클레스를 다시 토글
		this.classList.toggle("opening");
	},500);
});

여기서 두 번째 this는 부모로부터 상속되며 const box로 설정된다.

예제 코드를 실행하면 div가 0.5초 안에 빨간색으로 변하는 것을 볼 수 있다.

화살표 함수를 피해야 하는 경우

this 키워드의 상속에 대해 알았으니, 화살표 함수를 사용하면 문제가 될 수 있는 상황을 정리해보자.

다음 예는 화살표 함수에서 this를 주의해서 사용해야 하는 경우이다.

const button = document.querySelector("btn");
button.addEventListenner("click",()=>{
	// 오류 : 여기서 this는 window 객체를 가리킴
	this.classList.toggle("on");
});

다음과 같은 예도 마찬가지다.

const person1 = {
	age: 10,
	grow: function(){
		this.age++;
		console.log(this.age);
	}
};

person1.grow();
// 11

const person2 = {
	age: 10,
	grow: () => {
		// 오류 : 여기서는 this는 Window 객체를 가리킴
		this.age++;
		console.log(this.age);
	},
};

person2.grow();

화살표 함수와 일반 함수의 또 다른 차이점은 arguments 객체에 대한 접근 방식이다.

arguments 객체는 함수 내부에서 접근할 수 있는 배열 객체이며, 해당 함수에 전달된 인수의 값을 담고 있다.

간단한 예를 살펴보자.

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

이와 같이 배열 표기법 arguments[0]을 사용하면 첫 번째 인수에 접근할 수 있다.

this 키워드와 비슷하게, 화살표 함수에서 arguments 객체는 부모 스코프의 값을 상속한다.

앞에서 본 예제의 runners 배열을 응용한 다음 예를 살펴보자.

const showWinner = () => {
	const winner = arguments[0];
	console.log(`${winner} was the winner`);
};

showWinner("Usain Bolt", "Justin Gatlin", "Asafa Powell");

이 코드는 다음을 반환한다.

ReferenceError : arguments is not defined

함수에 전달된 모든 인수를 접근하려면, 기존 함수 표기법이나 스프레드 문법(9장에서 자세히 소개한다.)을 사용하면 된다.

여기서 arguments는 변수 이름이 아니라 키워드라는 점에 유의하자.

화살표 함수로 arguments에 접근하는 예는 다음과 같다.

const showWinner = (...args) => {
	const winner = args[0];
	console.log(`${winner} was the winner`);
};
showWinner("Usain Bolt", "Justin Gatlin", "Asafa Powell");
// Usain Bolt was the winer

이를 일반 함수로 구현하면 다음과 같다.

const showWinner = function(){
	const winner = arguments[0];
	console.log(`${winner} was the winner`);
};
showWinner("Usain Bolt", "Justin Gatlin", "Asafa Powell");
// Usain Bolt was the winer

참고 : 모던 자바스크립트 가이드

profile
-Keep Humble-

0개의 댓글