화살표 함수, Rest 파라미터

화살표 함수

ES6부터 지원되는 화살표 함수는 function 키워드 대신 =>를 이용하여 함수를 정의하게 해주는 방법이다.

const arrow = () => {};

와 같이 정의하며, 일반 함수와의 차이점만 간단하게 알아보자.
먼저 생성자 함수로 호출할 수 없는 non-constructor이며, 일반 함수에서 strict mode처럼 중복된 매개변수 이름을 사용할 수 없으며 화살표 함수 내부에서 this, arguments, super, new.target를 참조할 시 자체 바인딩이 없으므로 상위 스코프의 것을 참조한다.
여기서 자체 바인딩이 없다는 부분이 핵심인데, 이전에 콜백 함수와 같은 상황에서의 this 바인딩의 문제점을 알아본 적이 있었다. 그것을 화살표 함수로 해결하면 다음과 같다.

class Prefixer {
 constructor(prefix) {
  this.prefix = prefix;
 }
 add(arr) {
  return arr.map(item => this.prefix + item);
 }
}
const prefixer = new Prefixer('-webkit-');
console.log(prefixer.add(['transtion','user-select]));

여기서 만약 일반 함수가 콜백 함수로 전달되었다면 전역의 this를 참조할 것이다. 그렇지만 화살표 함수는 자체의 this 바인딩이 없고 lexical this를 가진다. 즉 함수가 정의된 위치의 상위 스코프의 this를 그대로 참조하게 된다. 그러므로 출력 결과는 ['webkit-transition'.'-webkit-user-select']가 될 것이다.

조금 이해를 돕자면 이런 셈이다.

const counter = {
 num:1,
 increase:() => ++this.num //여기서 상위 스코프는 전역이다.
};
console.log(counter.increase()); //NaN

그렇지만 메서드를 정의할 때는 이 예제처럼 정의하면 의도한 결과가 나오지 않을 것이다. increase() {} 처럼 화살표 함수 대신 ES6 메서드 축약 표현을 사용해야 올바른 this 참조가 일어날 것이다.

클래스 필드에서 화살표 함수를 사용할 경우에도 프로토타입 메서드가 아니라 인스턴스 프로퍼티로 할당될 것이므로 이런 경우에는 ES6 메서드 축약 표현을 사용하자.

class Person {
 name ='Kim';
 sayhi = () => console.log(`Hi &{this.name}`);
}

이런 경우에 화살표 함수의 상위는 Person인데 여기서 this는 생성할 인스턴스를 가리킬 것이기에 this.sayhi = 과 같아져 인스턴스 프로퍼티가 될 것이기 때문이다.
super, arguments도 마찬가지로 자체의 바인딩이 없으므로 상위 스코프를 참조한다.

Rest 파라미터

Rest 파라미터는 매개변수 이름 앞에 ...를 붙여 전달된 인수들의 목록을 배열로 전달받는 방법이다. 이것은 반드시 마지막 파라미터여야 하며, 하나의 Rest 파라미터만 가져야 하고, length에 영향을 주지 않는다.
arguments 객체와 다른 점은 arguments 객체는 배열이 아닌 유사 배열 객체이므로 배열 메서드를 사용할 수 없었다는 점을 보완하였고, 화살표 함수는 arguments 객체를 갖지 않기 때문에 Rest를 사용하면 더 편하다는 차이가 있다. 간단히 정리하면 다음과 같다.

function foo(param, ...rest){
 console.log(param); //1
 console.log(rest); //[2,3,4,5]
}
foo(1,2,3,4,5);

그리고 Rest 파라미터는 기본값을 지정할 수 없다.

function logName(name = 'Kim'){
 console.log(name); //인수를 전달하지 않았을 때나 undefined를 전달 했을 때의 기본값. Rest는 불가능하다.
}

좋은 웹페이지 즐겨찾기