Arrow function

사용법

//기존의 function sample
var double = function(x){
    return x*2;
}
//arrow function sample
const double = (x) => {
    return x*2;
}
//매개변수가 1개인 경우 소괄호 생략 가능
const double = x => {return x*2}
//함수가 한줄로 표현가능하면 중괄호 생략 가능하고 자동으로 return됨
const double = x => x * 2
//매개변수가 두 개 이상일 때
const add = (x,y) => x + y
//매개변수가 없을 때
() => {    ... }
//객체변환할 때 중괄호 사용
() => {return {a:1};}
//return 바로할땐 소괄호 사용
() => ({a:1})

function 키워드 대신 화살표(=>)를 사용하여 함수를 선언할 수 있다.

  • 미리 말하자면 arrow function이 기존의 function을 완전히 대신할 수 없다.
  • 콜백 함수에서 사용하면 아주 간결하게 표현이 가능한 장점이 있다.

함수 호출

//const pow = (x) => {return x * x;}
const pow = x => x * x;
console.log(pow(10)); // 100
//콜백에 arrow function 사용해서 간략화 시키기
const arr = [1,2,3];
const pow = arr.map(x => x * x);
console.log(pow);

변경점

  1. 매개변수에 default 값 적용 가능
const f1 = (msg ='jeongpro') => {
    alert(msg);
}
f1(); // 'jeongpro'

기존에는 매개변수를 전달하지 않으면 undefined가 나오지만 ES6에서는 실수로 매개변수를 전달하지 않았을 때 처리를 할 수 있다.

  1. arguments 대신 args 사용
var foo = function(){
    console.log(arguments);
}
foo(1,2); // { '0':1, '1':2 }

매개변수를 지정하지 않아도 arguments 라는 프로퍼티가 함수에 자동으로 생성되어 사용가능 했었으나 화살표 함수에는 arguments가 없어짐. 대신 args가 생겼다.

// ES5
function sum(){
  var arr = Array.prototype.slice.call(arguments);
  return arr.reduce(function(pre, cur){
    return pre + cur;
  });
}
console.log(sum(1,2,3,4));

// ES6
const sum1 = (...args) => {
  return args.reduce((pre, cur) => pre + cur);
}
console.log(sum1(1,2,3,4));

매개변수부분에 rest 파라미터(...)를 사용하여 가변인자 함수 내부에 배열로 전달할 수 있음.

  1. this 변경점 (핵심)
  • arrow function은 자신을 포함하는 외부 scope에서 this를 계승받는다.
    즉, arrow function은 자신만의 this를 생성하지 않는다. (Lexical this)
function Prefixer(prefix) {
  this.prefix = prefix;
}

Prefixer.prototype.prefixArray = function (arr) {
  console.log(this.prefix);// (A)
  return arr.map(function (x) {
    return this.prefix + ' ' + x; // (B)
  });
};

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

this.prefix가 (A)에서는 'Hi' 를 나타내지만 (B)에서는 undefined가 찍힌다.
지난 포스트에서 자바스크립트의 this에서 봤듯이 내부 함수호출에서는 this가 window객체였다.

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

Prefixer.prototype.prefixArray = function (arr) {
  return arr.map(x => `${this.prefix}  ${x}`);
};

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

arrow function에서는 내부 함수여도 this가 arrow function이 선언된 곳에서 상위의 context를 가리키므로 Prefixer객체 pre를 가리키므로 this.prefix가 Hi를 가리켜 개발자가 예상한대로 작동한다.

arrow function을 사용하면 안되는 경우1

const obj1 = {
  name : 'Lee',
  sayName : () => {console.log(`hi + ${this.name}`);}
};
obj1.sayName();
Colored by Color Scripter

위와 같이하면 객체의 this를 바인딩하지 않고 전역 객체가 바인딩된다.

즉, 객체의 메소드를 정의할 때는 사용하면 안된다.

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

obj.sayHi(); // Hi Lee

위 처럼 ES6에서 사용하는 객체의 메소드 정의방법으로 정의하는 것이 옳다. 마찬가지로 prototype에 메소드를 할당할 때도 똑같이 화살표함수를 사용하면 안된다.

일반 함수 function(){ } 을 이용하도록 한다.

arrow function을 사용하면 안되는 경우2

arrow function을 생성자 함수로 사용할 수 없음.

arrow function을 사용하면 안되는 경우3

addEventListener 함수의 콜백 함수에서 사용하면 this가 상위 컨텍스트를 가리킴

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

var button = document.getElementById('myButton');  
button.addEventListener('click', function() {  
  console.log(this === button); // => true
  this.innerHTML = 'Clicked button';
});
Colored by Color Scripter

+ Recent posts