ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [es6] 함수형 프로그래밍과 JavaScript ES6+
    Web/JavaScript 2020. 7. 8. 17:14

    블록 (개인적으로 추가)

    const / let : block 단위

    var : function단위

     

    평가

    - 코드가 계산 되어 값을 만든는 것을 의미한다.

     

    일급

    - 값으로 다룰수 있다.

    - 변수에 담을 수 있다.

    - 함수의 인자로 사용될 수 있다.

    - 함수의 결과로 사용될 수 있다.

    <script>
    	const a = 10;
        const add10 = a = > a+10;
        const r = add10(a);
        log(r);
    </script>

    위와 같은 코드는 클로저 패턴으로 볼수 있는데, 클로저는 외부함수의 변수에 접근하기 위해 내부 함수를 사용하는 것이다. 

     

    일급 함수

    - 함수가 값으로 다뤄질 수 있다.

    - 조합성과 추상화의 도구로 함수를 잘 사용할 수 있다.

    - 함수가 일급이라는 것은 함수의 결과값으로 함수를 사용할수 있다는 것을 뜻한다.

     

    고차 함수

    - 함수를 값으로 다루는 함수

    1. 함수를 인자로 받아서 실행하는 함수
    2. 함수를 만들어 리턴하는 함수( 클로저를 만들어 리턴하는 함수 )

    리스트 순회

    - es6에서 리스트 순회가 많이 바뀌었다.

     

    기존의 방식에서

    const log = console.log;
    
    const list = [1,2,3];
        for ( var i = 0; i < list.length; i++){
        log(list[i]);
    }
    

    새로운 방식으로 구현한다.

    const log = console.log;
    
    for(const a of list){
        log(a);
    }

     

    Array를 통해서 구현

    - javascript는 Array, set, Map의 내장값들을 가지고 있다.

    const log = console.log;
    
    const arr = [1,2,3];
    for(const a of arr){
    	log(a)
    }
    
    const set = new Set([1,2,3]);
    for(const a of arr){
    	log(a)
    }
    
    const map = new Map([['a',1],['b',2],['c',3]]);
    for( const a of map){
    	log(a)
    }

    실행시 위와 같은 결과가 나온다.

     

    이때 한가지 의문점 기존의 for문처럼 index기반으로 동작하는가?

    Symbol.iterator에 담겨있는 함수와 연관이 있다.

    done이 true가 될때까지 실행된다.

    이터러블 / 이터레이터 프로토콜

    - 이터러블: 이터레이터를 리턴하는 [Symbol.iterator] 를 가진 값 (array == 이터러블)

    - 이터레이터: { value, done } 객체를 리턴하는 netxt()를 가진 값

    - 이터러블/ 이터레이터 프로토콜: 이터러블을 for ...of, 전개 전산자 와 함께 동작하도록 한 규약

     

    제너레이터

    - 이터레이터이자 이터러블을 생성하는 함수

    function *gen() {
        yield 1;
        if (false) yield 2;
        yield 3;
        return 100;
       }
       let iter = gen();
       log(iter.next());
       log(iter.next());
       log(iter.next());
       log(iter.next());
    
       for(const a of gen()) log(a)

     

    실행결과

    map

     const products = [
            {name: '반팔티', price:15000},
            {name: '긴팔티', price:20000},
            {name: '핸드폰케이스', price:15000},
            {name: '후드티', price:30000},
            {name: '바지', price:25000}
        ];
        
     	let names =[];
        for (const p of products){
            names.push(p.name);
        }
    	log(names);    
        
        let prices =[];
        for (const p of products){
            prices.push(p.price);
        }
        log(prices);

    map을 사용하면 위의 보기에서 아래의 보기로 코드를 변경할 수 있다.

    const products = [
            {name: '반팔티', price:15000},
            {name: '긴팔티', price:20000},
            {name: '핸드폰케이스', price:15000},
            {name: '후드티', price:30000},
            {name: '바지', price:25000}
        ];
        
        const map =(f, iter) =>{ 
        let res =[];
            for (const a of iter){
                res.push(f(a));
            }
            return res;
        };
        
        log(map(p=>p.name, products));
        log(map(p=>p.price, products));

    map에 보조함수를 통해 이터러블안에 어떤 값을 수집하겠다고 전달하는 방식이다.

     

    map에 값을 넣고 새로운 키, 벨류를 만들어 새로운 Map객체 생성하기

    let m = new Map();
    m.set('a',10);
    m.set('b',20);
    log(new Map(map(([k, a]) => [k, a * 2], m)));

    filter사용법

      const products = [
        { name: '반팔티', price: 15000 },
        { name: '긴팔티', price: 20000 },
        { name: '핸드폰케이스', price: 15000 },
        { name: '후드티', price: 30000 },
        { name: '바지', price: 25000 },
      ];
      
      let under20000 = [];
      for (const p of products) {
        if (p.price < 20000) under20000.push(p);
      }
      log(...under20000);
    
      let over20000 = [];
      for (const p of products) {
        if (p.price >= 20000) over20000.push(p);
      }
      log(...over20000);

    filter를 사용하면 위의 코드에서 아래 코드로 변경된다.

      const filter = (f, iter) => {
        let res = [];
        for (const a of iter) {
          if (f(a)) res.push(a);
        }
        return res;
      };
        log(...filter((p) => p.price < 20000, products));
        log(...filter((p) => p.price >= 20000, products));

    결과값

    reduce함수

    reduce는 log(add(add(add(add(add(01), 2), 3), 4), 5)); 이런식으로 이뤄져 있다.

    재귀적으로 연속적으로 실행하여 값을 누적하면서 하나의 값으로 만들어 가는 방법이다.

      const reduce = (f, acc, iter) => {
        if (!iter) {
          iter = acc[Symbol.iterator]();
          acc = iter.next().value;
        }
        for (const a of iter) {
          acc = f(acc, a);
        }
        return acc;
      };
      const add = (a, b) => a + b;
      
      log(reduce(add, [1, 2, 3, 4, 5]));

     

      log(
        reduce((total_price, product) => total_price + product.price, 0, products),
      );

     

     

    map + filter + reduce

      const products = [
        { name: '반팔티', price: 15000 },
        { name: '긴팔티', price: 20000 },
        { name: '핸드폰케이스', price: 15000 },
        { name: '후드티', price: 30000 },
        { name: '바지', price: 25000 },
      ];
    
      const add = (a, b) => a + b;
      log(
        reduce(
          add,
          map(
            (p) => p.price,
            filter((p) => p.price < 20000, products),
          ),
        ),
      );
    
      log(
        reduce(
          add,
          filter(
            (n) => n < 20000,
            map((p) => p.price, products),
          ),
        ),
      );

    코드를 오른쪽에서 왼쪽으로 읽으면 편하다.

    가격이 20000원보다 작은 물품들의 값을 모두 더하는 식이다.

    함수형 프로그래밍은 이런식으로 동작한다.

     

    코드를 값으로 다루기

    어떤함수가 코드인 함수를 받아서 평가하는 시점을 원하는대로 다룰수 있기때문에 코드의 표현을 높일 수 있다.

     

     

     

    함수형 프로그래밍과 JavaScript Es6+ 수업

     

     

     

     

    반응형

    'Web > JavaScript' 카테고리의 다른 글

    [Javascript] type 추론  (0) 2020.02.10
    [ Javascript ] array 함수 정리  (0) 2020.02.10
    [ javascript ] !! 란? 느낌표 두개 의미  (0) 2020.01.08
    [ JS ] Custom Tag 제거 방법 ( intellij )  (0) 2019.12.11
    [ JS ] Blob이란?  (0) 2019.12.11

    댓글

Designed by Tistory.