자바스크립트 화살표 함수 (array function)

2017-09-21
블로그 UI가 개편중입니다. 참고해주세요.

array func은 아래와 같은 간단한 형태를 보면 매우 간단하나, 복잡한 구문을 보면 매우 어렵게 느껴진다. 쉬운 array func 부터 복잡한 array func까지 절차적으로 밟아보자.

array func

array func의 특징을 정리해보자면 아래와 같이 간략하게 정리할 수 있다.

  • function에 비해 구문이 짧다.
  • 항상 익명이다.
  • this, arguments, super, new target을 바인딩하지 않는다.
  • 생성자로 사용할 수 없다.

문법

array func은 비슷비슷 하지만 결과가 다른 부분이 많기 때문에 간단한 라인이라도 처음에는 꼼꼼하게 보는 것이 좋다.

  • 기본 문법

    여기서 리턴이 필요하면 명시적으로 return을 선언한다.

    // 문법
    (매개변수1, 매개변수2, 매개변수3, 매개변수n) => { 구문 }
    
    // 리턴이 없는 예
    let test = (a) => { console.log(a) }
    let testVal = test(1); //console.log -> 1
    console.log(testVal) // undefined
    
    // 리턴이 있는 예
    let test = (a, b, c) => { return a + b + c }
    let testVal = test(1,2,3);
    console.log(testVal) // 6
    
  • 간결한 리턴 문법

    오른쪽 구문에서 중괄호를 생략하면 array func에서는 자동으로 표현식을 리턴한다. 즉 return 생략이 가능하다.

    // 문법
    (매개변수1, 매개변수2, 매개변수3, 매개변수n) => 표현식
    
    // 예
    let test = (a, b, c) => a + b + c
    let testVal = test(1,2,3);
    console.log(testVal) // 6
    
  • 매개변수가 하나인 경우 좌측 괄호 생략이 가능

    // 문법
    매개변수1 => 표현식
    매개변수1 => { 구문 }
    
    // 예
    let test = a => a + 10
    let testVal = test(1);
    console.log(testVal) // 11
    
    let test = a => { return a + 10 }
    let testVal = test(1);
    console.log(testVal) // 11
    
  • 객체 리터럴을 반환하는 식에는 우측에 괄호를 감쌈

    // 문법
    매개변수1 => ({name: 매개변수1})
    
    // 예
    let test = a => ({aVal: a})
    let testVal = test('에이');
    console.log(testVal) // {aVal: "에이"}
    
  • 매개변수에 기본값 셋팅이 가능

    // 문법
    (매개변수1 = 'default', 매개변수2) => { 표현식 }
    
    // 예
    let test = (a=10, b) => { return a + b }
    let testVal = test(undefined, 5);
    console.log(testVal); // 15
    
    // 주의: undefined 대신 null을 입력하면 기본값을 넣지 않는다.
    let testVal = test(null, 5);
    console.log(testVal); // 5
    
  • 매개변수는 펼침 연산자 사용 가능

    // 문법
    (...매개변수n) => { 표현식 }
    
    // 예
    let test = (...args) => { console.log(args) }
    test(1,2,3,4,5) // console.log -> [1,2,3,4,5], return -> undefined
    
  • 매개변수에 비구조화된 매개변수 또한 사용 가능

    var f = ([a, b] = [1, 2], {x: c} = {x: a + b}) => a + b + c;
    // 중간과정 해석
    // ([a, b] = [1, 2])  >>  a = 1, b = 2 할당
    // {x: c} = {x: a + b}  >> a+b 를 선 계산 후 오른쪽 x 에 할당, 할당된 x 는 다시 왼쪽 x에 할당되면서 c = 3이 할당
    // 즉 a=1, b=2, c=3 이 됨.
    f();  // 6
    

function과 다른 점

가장 중요한 특징은 this, arguments가 자동으로 바인딩이 되지 않는다는 것이다. 보통 일반 func 같은 경우는 아래와 같다.

let scopeTest = {
    run: function () {
        console.log(this);
        console.log(arguments);
    }
}

scopeTest.run();
// console.log -> {run: ƒ}
// console.log -> [callee: ƒ, Symbol(Symbol.iterator): ƒ]

하지만 아래와 같이 array func을 이용하면 에러가 발생한다.

let scopeTest = {
    run: () => {
        console.log(this);
        console.log(arguments);
    }
}

scopeTest.run();
// console.log -> Window {stop: ƒ, open: ƒ, alert: ƒ, confirm: ƒ, prompt: ƒ, …}
// console.log -> Uncaught ReferenceError: arguments is not defined
// console.log ->    at Object.run (<anonymous>:4:21)
// console.log ->    at <anonymous>:8:11

사용예제

위에서 간략하게 array func의 사용법과 특징을 배웠으니 이번에는 예제를 통해 익혀보자. 처음 접하는 문법을 빠르게 익힐때에는 쉬운 문법부터 복잡한 문법까지 절차적으로 익혀가되 해당하는 문법을 완벽하게 이해하고 넘어가야 도움이 된다.

아래는 array func과 일반 func으로 번갈아가며 비교해본다.

  • 기초

    // array function
    let resultlVal = () => { console.log('test'); }
    // function
    function resultVal() {
      console.log('test');
    }
    
    // array function
    let resultlVal = (...args) => { console.log(args); }
    // function
    function resultVal(...args) {
      console.log(args);
    }
      
    // array function
    let resultlVal = (...args) => args;
    // function
    function resultVal(...args) {
      return args;
    }
    
  • 함수 내 함수

    1번 예제에서는 return 값이 없기 때문에 이 args.map에 대한 연산은 undefined의 배열이 된다.

    // 1
    // array function
    let result = (...args) => val => args.map(a => {a + val})
    // function
    function result (...args) {
      return function(val) {
        return args.map(function(a) {
          a + val; 
        });
      }
    }
    
    // 2
    // array function
    let result = (...args) => val => args.map(a => a + val)
    // function
    function result (...args) {
      return function(val) {
        return args.map(function(a) {
          return a + val;
        });
      }
    }
    
  • 기타 array func 사용법

    필자가 callback 패턴을 promise 패턴으로 바꾸는 방법 중 가장 자주 사용하는 방법은 아래와 같은 promiseWrapper함수 유틸을 만들고 사용하는 방법이다. 이 로직 역시 array func으로 아래와 같이 작성할 수 있다.

    // array function
    function promiseWrapper (func, ...args) { 
        return new Promise(resolve => func(...args, ...returnArgs => resolve(returnArgs)));
    };
    // function
    function promiseWrapper (func, ...args) {
      return new Promise(function(resolve) {
        return func(...args, function(...returnArgs) {
          return resolve(returnArgs);
        })
      })
    }
    

커링 (currying)

array func의 기본기를 알아보았으니 이번에는 커링도 한번 해보도록 하자. 커랑이란 간단하게 이야기하자면 함수의 인자를 고정시켜 적용하는 함수를 만드는 기법이다.

아래는 합을 구하는데 커링 기법을 이용한 것이다.

let sumCurry = fixNum => input => fixNum + input;

사실 위에 있는 예제들도 커링 기법이 적용된 예제들이 많다.

주의사항

  • 줄바꿈 주의

    화살표 함수는 파라메터와 화살표 사이에 개행 문자를 포함 할 수 없다.

    // error
    var func = ()
            => 1; // SyntaxError: expected expression, got '=>'
    
  • 파싱순서 주의

    let callback;
    
    callback = callback || function() {}; // ok
    callback = callback || () => {};      // SyntaxError: invalid arrow-function arguments
    callback = callback || (() => {});    // ok
    
  • undefined 주의

    let empty = () => {};
    // empty = undefined
    
  • 매개변수가 없을 시 주의

    // => { statements } error
    () => { statements }
    
Prev
Next

익스플로러 브라우저 close event 감지

요즘 socket.io를 이용해서 웹 채팅 화면을 구현중이다. ie 요구사항은 9 버젼부터이다. ie9는 웹소켓을 사용할 수 없어서 폴링방식을 이용하여 통신하는데 아래과 같은 close 상황일 때에 문제가 발생하였다. 탭 창이 닫힌 경우 F5를 눌러서 새로고침 한 경우 ctrl + r을 눌러서 새로고침...

typescript에서 ie9 window.console bug 수정하기

ie와의 지독한 싸움이 아직도 끝나지 않았다. 예전에 ie9에서 작업할 때 꼭 디버깅 창을 열어야 javascript 소스가 실행되는 현상이 있었다. 알고보니 ie9 버그로써 디버그 창을 열어야 console을 인식하고, 디버그 창을 열지 않으면 console이라는 문자열이 js에 찍히는 순간 javascript가 에러나서 종료되는 현상이였다....

nodejs cluster 프로세스에서 데이터 공유하기

nodejs의 cluster는 기본적으로 child_process의 기능을 바탕으로 만들어졌다. master process와 worker process는 프로세스간 통신할때 일반적으로 사용되는 IPC를 사용하여 서로 통신한다. 또한 cluster 모듈을 사용할 때 공식적으로 프로세스간에 공유하는 메모리는 없다. 따라서 같은 메모리 주소값을 참조해서 데이터를 사용하는 방법 역시 없다. 하지만...

webpack으로 nodejs 서버사이드 개발시 옵션

webpack으로 nodejs server-side를 작성하려고 하니까 모듈 exports나 기타 모듈 관계 생성이 잘 동작하지 않는다. webpack의 기본 옵션은 front-side로 맞춰져 있기 때문이다. server-side에서 바로 시작할 수 있게끔 webpack의 가장 중요한 옵션을 정리해본다. config file 수정 아래를 참고해서 3부분을 수정하면 바로 server-side용으로...