[TIL] 화살표 함수

Sohee Yeo·2022년 5월 18일
0

TIL

목록 보기
22/23
post-thumbnail

Today I Learned📚


화살표 함수


function 키워드 대신 화살표 => 를 사용하여 기존의 함수 정의 방식보다 간략하게 함수를 정의할 수 있다.

기존 함수 표현식에서 function 키워드를 삭제하고 매개변수의 () 와 코드블록{} 사이에 화살표 ⇒ 를 넣어준다.

함수 내부에 반환값(return)만 있다면 {}와 return도 생략할 수 있다.

const sum = function(a, b) {
	return a + b;
};
화살표 함수로 바꿔보기
const sum = (a, b) => a + b;

화살표 함수 특징


  • 화살표 함수는 함수 선언문으로 정의할 수 없고 함수 표현식으로 정의해야 한다.

(함수 표현식: 변수에 함수를 할당하는 것)

화살표 함수는 함수를 식별할 수 있는 식별자가 없기 때문에 표현식으로 작성해야 호출이 가능하다.

const sum = (x, y) => x + y;

sum(2, 3); 

// 5

  • 매개 변수 선언
// 매개변수가 여러 개인 경우 소괄호() 안에 선언
const arrow = (x, y) => { ... }; 
                         
// 매개변수가 한 개인 경우 소괄호() 생략 가능
const arrow = x => { ... }; 
                    
// 매개변수가 없는 경우 소괄호() 생략 불가
const arrow = () => { ... } 

  • 함수 몸체 정의

▫ 함수 몸체가 하나의 문으로 구성되면 {} 생략이 가능하다.

▫ 하지만 함수 몸체가 여러 개의 문이라면?
중괄호 {} 를 생략할 수 없다. 또한 반환값(return)을 명시적으로 반환해야 한다.

const sum = (a, b) => {
	const result = a + b;
	return result;
};

▫ 객체 리터럴을 반환하는 경우 객체 리터럴을 소괄호()로 감싸 주어야 한다.

const member = (name, address) => { return { id, address }; };

const member = (id, password) => ({id, password});

겉에 있는 중괄호를 제거하고 return을 제거한다면, 코드 자체가 화살표 함수의 중괄호처럼 인식될 수 있기 때문!

▫ 화살표 함수도 즉시 실행 함수로 사용할 수 있다.

(function () {
  var a = 3;
  var b = 5;
  return a * b;
})();
화살표 함수로 바꿔보기
(() => {
  var a = 3;
  var b = 5;
  return a * b;
})();


화살표 함수와 일반 함수의 차이


  • 화살표 함수는 인스턴스를 생성할 수 없는 non-constructor이다.

생성자 함수로 호출할 수 없기 때문에 property가 없고, prototype도 생성하지 않는다.
또한 new 연산자와 함께 사용할 수 없다.

  • 중복된 매개변수 이름을 선언할 수 없다.
//일반함수
function hey(a, a) {return a + a}
console.log(hey(1, 2));
// 4

// 화살표 함수
const hey = (a, a) => a + a;

// Uncaught SyntaxError: Duplicate parameter name not allowed in this context
  • 화살표 함수는 함수 자체의 this, arguments, super, new.target 바인딩을 갖지 않는다.
    스코프 체인을 통해 상위 스코프를 참조한다.
    중첩 화살표 함수에서는 가장 가까운 상위 함수 중 참조한다.

화살표 함수에서의 this

화살표 함수의 this는 일반 함수의 this와 다르게 동작한다. 화살표 함수는 자체의 this 바인딩을 갖지 않아 상위 스코프의 this를 참조한다. (Lexical this)

//일반함수
let group = {
  title: '강남 모각코 스터디',
  members: ['민영', '지수', '희', '다은', '소희', '준상', '지훈'],

 showList() {
    this.members.forEach(function(member) { 
      // TypeError: Cannot read property 'title' of undefined
      alert(this.title + ': ' + member) 
    });
  }
};

group.showList();

→ 일반 함수에서 this는 메서드를 호출한 객체를 가리킨다. 첫 번째 this는 group을 가리키고, 두 번째 this는 전역객체인 window를 가리킨다. 콜백 함수 내부의 this는 전역 객체를 가리키므로.

// 화살표 함수
let group = {
  title: '강남 모각코 스터디',
  members: ['민영', '지수', '희', '다은', '소희', '준상', '지훈'],

 showList() {
    this.members.forEach( 
      member => alert(this.title + ': ' + member) 
    );
  }
};

group.showList();

forEach에서 화살표 함수를 사용했기 때문에 화살표 함수 본문에 있는 this는 상위 스코프인 group의 this를 그대로 가져온다.

화살표 함수에서의 super

화살표 함수는 super을 지원하지 않는다.
화살표 함수 내부에서 super를 참조하면 this와 마찬가지로 상위 스코프의 super을 참조한다.

✔ super : 인스턴스의 프로토타입을 참조

class Robot {
   constructor(name) {
       this.name = name;
   }

   sayYourName() {
       return `삐리비리. 제 이름은 ${this.name}입니다. 주인님.`;
   }
}

class BabyRobot extends Robot {
           sayHi = () => `${super.sayYourName()} 무엇을 도와드릴까요?`;
       }

       const baby = new BabyRobot('자비스');

화살표 함수는 생성자 함수가 아니기 때문에 super로 프로토타입을 참조할 수 없다.
화살표 안의 super은 스코프 체인으로 상위 함수인 BabyRobot를 참조하고, Derived의 부모함수인 Robot의 프로토타입을 참조한다.

화살표 함수에서의 argument

화살표 함수는 인수에 접근할 수 있게 해주는 유사 배열 객체 arguments를 지원하지 않는다. 따라서 화살표 함수 내부에서 arguments를 참조할 때는 상위 스코프의 arguments를 참조한다.

function dessert(){
    console.log(arguments);
}
dessert('초콜릿', '쿠키', '케이크');

// Arguments(3) ['초콜릿', '쿠키', '케이크', callee: ƒ, Symbol(Symbol.iterator): ƒ]

함수는 기본적으로 arguments객체가 내장되어 있어 유사 배열 객체로 출력된다.

// 화살표 함수
const coffee = () => {
    console.log(arguments);
}
coffee('아메리카노', '카페라떼', '카푸치노');

// VM390:2 Uncaught ReferenceError: arguments is not defined

화살표 함수는 argument를 지원하지 않으므로 에러가 뜬다.
대체하기 위해서 rest 파라미터를 사용하면 된다.

new.target

new.target은 함수나 생성자가 new 연산자를 사용했는지 감지하는 역할을 한다.




참고 사이트

https://ko.javascript.info/arrow-functions-basics

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions

profile
실패에 무딘 사람. 프론트엔드 개발자를 꿈꿉니다

0개의 댓글