DevLog__[javascript: 고차함수]

Jaewon Lee·2020년 10월 1일
0

Javascript

목록 보기
7/12
post-thumbnail

# Intro

요새 블로그 쓰는 양식을 바꿀까 생각중이다. 소나무 처럼 한결 같이 냅다 10편 정도 쓰니까 뭔가 블로그가 심심하기도....재미없어 보이기도...하다. 하기사 개발하는 사람 아니면 재미가 없긴 하겄지? 블로그를 어떻게 하면 재밌게 만들 수 있을까하는 생각이 많아졌다. 춤이라도 춰야하나....

얼마전에 스터디원 분이 한 블로그를 알려 주셔서 들어가 봤는데, 티스토리 블로그였다. 뜨거운 블로그라서 그런지 광고도 붙어있던데....부럽다ㅎ 그게 중헌것이 아니라, 게시글 마다 정성스럽게 작성한 것이 딱 봐도 보였다. 가독성도 좋고, 순차적으로 그림이나, 스크린샷과 같은 이미지를 통해 설명해 줘서 이해가 잘 된다. 사실 그림 넣는거...조금 귀찮다. 하지만 나도 이미지를 첨부하면서 하려고 한다. 백날 말로 설명해봤자 눈으로 한번 보는 것이 낫지않은가!

하지만 오늘 하는 고차함수는 그런거 안들어간다. javascript에서 들어갈 일이 있을까 싶다...끽 해야 코드 정도....이해가 안가면 코드 열심히 봐줬으면 한다. 코드를 봐도 이해가 안가면 나를 밟고가라....

# javascript

자바스크립트!!!!! 오늘은 고차함수 가즈아!!!!!!!!!!!🔥


1. 고차함수


1) 고차함수가 뭐에요?

  • 함수를 인자로 받거나 함수를 리턴하는 함수

2) First-class citizen (일급 객체)

  1. 자바스크립트에서 '함수'는 특별한 취급을 받는다. 마치 비행기 일등석에 앉는 손님처럼!

  2. 함수를 변수에 저장할 수 있다.

    • 함수 표현식이라고 한다.
    • 함수 선언식에 지나치게 의존하는 것은 코드의 유지 보수 측면에서 좋지 않다.
    • 호이스팅을 제외하면 함수 선언식과 함수 표현식의 차이는 크게 없다.
  3. 다른 함수의 인자(argument)로 전달 될 수 있다.

  4. 다른 함수의 결과로서 리턴 될 수 있다.

3) 고차함수의 종류

Callback 함수

  • 다른 함수의 '인자'로 들어가는 함수
function double(num) {
  return num * 2;
}
function doubleNum(func, num){
  let doubledArr = [];
  return func(num);
}
// 함수 doubleNum은 다른 함수를 인자로 받는 고차 함수이다.
// 함수 doubleNum의 첫 번째 인자 func는 doubleNum의 콜백 함수이다.
// 아래와 같은 경우, 함수 double은 함수 doubleNum의 콜백 함수이다.
let output = doubleNum(double, 4);
console.log(output);                     // OUTPUT: 8

Currying 함수

  • 함수를 리턴하는 경우
  • 클로저 유용한 예제편에서 다뤘음.
function adder(added) {
  return function (num) {
    return num + added;
  };
}
// 함수 adder는 다른 함수를 리턴하는 고차 함수이다.
// adder는 인자 한 개를 입력받아서 함수(익명 함수)를 리턴한다.
// 리턴되는 익명 함수는 인자 한 개를 받아서 added와 더한 값을 리턴한다.
// adder(5)는 함수이므로 함수 호출 연산자 '()'를 사용할 수 있다.
let output = adder(5)(3);
console.log(output);            // OUTPUT: 8
// adder가 리턴하는 함수를 변수에 저장할 수 있다.
// javascript에서 함수는 일급 객체이기 때문이다.
const add3 = adder(3);
output = add3(2);
console.log(output);            // OUTPUT: 5

함수를 인자로 받고, 함수를 리턴하는 경우

  • 커링과 콜백 짬뽕시켜도 됨
function double(num) {
  return num * 2;
}
function doubleAdder(added, func) {
  const doubled = func(added);
  return function (num) {
    return num + doubled;
  };
}
// doubleAdder는 고차 함수이다.
// doubleAdder의 인자 func는 doubleAdder의 콜백 함수이다.
doubleAdder(5, double)(3);              // OUTPUT: 13
// doubleAdder가 리턴하는 함수를 변수에 저장할 수 있습니다. (일급 객체)
const addTwice3 = doubleAdder(3, double);
addTwice3(2);                           // OUTPUT: 8

4) 추상화 (abstraction)

추상화란?

  • 추상화의 다른 말은 요약이다.
  • 복잡한 어떤 것을 압축해서, 핵심만 추출하려는 상태로 만드는 것이 추상화이다.
  • 쉽게 말해서, Input에서 Ouput이 나오기까지의 논리적 구조가 숨겨져 있는 상태를 말함.
  • 이것도 어렵다면, 우리가 로그인 할 때를 예로 들어보자. 우리는 로그인 버튼을 눌렀을 때 정확히 어떤일이 벌어지는지 모를꺼야. 그저 id와 password를 제대로 입력하면 로그인이 될 것이라는 것만 알지! 이게 바로 추상화단 말이다.

추상화의 종류

  • 값 수준의 추상화 : 값을 받아 값을 리턴한다. (값에 대한 로직은 숨겨져있다.)
  • 사고의 추상화 : 함수를 전달받거나, 함수를 리턴한다. (함수에 대한 복잡한 로직은 숨겨져있다.)

고차함수에서 추상화가 가지는 장점

  • 추상화의 수준이 올라갈 수록 코드의 생산성이 비약적으로 상승한다.
  • 생산성이 왜 올라가나?
    1. 추상화의 수준이 올라가는 것은 input과 output 사이의 Logic이 더욱 복잡해지는 것을 말한다.
    2. Logic은 함수간의 상호작용이다.
      • input1 👉 함수1 👉 함수2 👉 함수3 👉 ouput1
      • Logic : 함수1 ~ 함수3
    3. Logic이 복잡할 수록, 이를 구성하는 함수들은 더욱 세분화가 된다.
      • input1 👉 함수1_1 👉 함수1_2 👉 함수2_1 👉 함수2_2 👉 함수3_1 👉 함수3_2 👉 output1
    4. 함수가 맡은 역할이 더욱 간소해지는 것이다.
    5. 역할이 간소해지면, 때에 따라 원하는 목적에 맞게 함수를 재구성할 수 있다.
      • input2 👉 함수1_1 👉 함수2_2 👉 함수3_2 👉 output2
    6. 사전에 만든 함수의 재사용이 증가하는 것이다.
    7. 이것을 보고 코드의 생산성이 높아진다고 한다.

5) 배열 관련 고차함수

filter

let arr = [1, 2, 3, 4, 5, 6]
arr.filter(function(item){
  return item%2 === 0
})
// OUTPUT : [2, 4, 6]

map

let arr = [1, 2, 3, 4, 5, 6]
arr.map(function(item){
  return item*2
})
// OUTPUT : [2, 4, 6, 8, 10, 12]

forEach

let arr = [1, 2, 3, 4, 5, 6]
arr.forEach(function(item){
  console.log(item)
})
// OUTPUT : 1
//          2
//          3
//          4
//          5
//          6

reduce

  • reduce의 두번째 인자로 accumulate 값을 초기화할 수 있다.
let arr = [1, 2, 3, 4, 5, 6]
// version.1.
arr.reduce(function(acc, curr, index, arr){
  console.log(`누적값: ${acc}, 현재값: ${curr}, index: ${index}, arr: ${arr}`)
  return acc+curr
},0)
// OUTPUT : 누적값: 0,  현재값: 1, index: 0, arr: 1, 2, 3, 4, 5, 6
//          누적값: 1,  현재값: 2, index: 1, arr: 1, 2, 3, 4, 5, 6
//          누적값: 3,  현재값: 3, index: 2, arr: 1, 2, 3, 4, 5, 6
//          누적값: 6,  현재값: 4, index: 3, arr: 1, 2, 3, 4, 5, 6
//          누적값: 10, 현재값: 5, index: 4, arr: 1, 2, 3, 4, 5, 6
//          누적값: 15, 현재값: 6, index: 5, arr: 1, 2, 3, 4, 5, 6
//          21
// ----------------------------------------------------------------
// ----------------------------------------------------------------
// version.2.
arr.reduce(function(acc, curr, index, arr){
  console.log(`누적값: ${acc}, 현재값: ${curr}, index: ${index}, arr: ${arr}`)
  return acc+curr
})
// OUTPUT : 누적값: 1,  현재값: 2, index: 1, arr: 1, 2, 3, 4, 5, 6
//          누적값: 3,  현재값: 3, index: 2, arr: 1, 2, 3, 4, 5, 6
//          누적값: 6,  현재값: 4, index: 3, arr: 1, 2, 3, 4, 5, 6
//          누적값: 10,  현재값: 5, index: 4, arr: 1, 2, 3, 4, 5, 6
//          누적값: 15, 현재값: 6, index: 5, arr: 1, 2, 3, 4, 5, 6
//          21

some

  • 배열의 요소중 1개라도 조건을 만족시키는 것이 있다면 true를 리턴한다.
let arr = [1, 2]
arr.some(function(item){
  return item%2 === 0
})
// OUTPUT : true

every

  • 배열의 모든 요소가 조건을 만족시켜야 true를 리턴한다.
let arr = [1, 2]
arr.every(function(item){
  return item%2 === 0
})
// OUTPUT : false

sort

let arr = [ 13, 12, 11, 10, 5, 3, 2, 1 ];
// 그냥 sort해버리면 아스키문자 순서로 정렬시켜버림
arr.sort();
console.log( arr ); 
// OUTPUT : [ 1, 10, 11, 12, 13, 2, 3, 5 ];
arr.sort( function( a, b ) {
  return a - b;
})
console.log( arr );
// OUTPUT : [ 1, 2, 3, 5, 10, 11, 12, 13 ]

# Work Off


고차함수 마스터함ㅋ 이제 filter, map, forEach, reduce 등 위에 있는 배열관련 고차함수 이지함ㅋ

하지만 벼는 익을수록 고개를 숙이는 법....연습하자...연습...

빨리 비동기호출, 함수메소드 공부하러가자.....흑흑

기본기가 탄탄한 풀스택 개발자가 되는 그날까지 🔥🔥🔥

profile
Communication : any

1개의 댓글

comment-user-thumbnail
2020년 10월 27일

그 티스토리 누군가요ㅎㅎ 저도 같이 보게요ㅋㅋ
이렇게 블로그 쓰는거 진짜 대단하신거 같아요. 이해도 잘되고 심지어 꼼꼼하고... 재밌어ㅠㅠ
저도 써야하는데 막막하네여ㅋㅋㅋ

답글 달기