일급객체와 고차함수

Judo·2020년 11월 9일
0
post-thumbnail

일급 객체(First-class citizen)

  • 특별한 대우를 받는 것 -> 그 중 하나가 함수(function)

  • 일급객체의 특징

    • 변수에 할당(assignment)할 수 있다.
    • 다른 함수의 인자(argument)로 전달될 수 있다.
    • 다른 함수의 결과로서 리턴될 수 있다.

    고차 함수(Higher order function)

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

  • 다른 함수(caller)의 인자로 전달되는 함수를 콜백 함수(callback function)라고 한다.

  • caller는 조건에 따라 함수에 실행여부를 결정.

    커리와 구별!

  • 커리 : 함수를 리턴하는 함수

  • 고차 함수 : 함수를 인자로 받거나 함수를 리턴하는 함수.

  • 고차 함수가 커리를 포함하는 개념

    • 구분할 경우 '커리 : 함수를 리턴하는 함수' , '고차함수 : 함수를 인자로 받는 함수'

    1. 다른 함수를 인자로 받는 경우

function double(num) {
  return num * 2;
}

function doubleNum(func, num) {
  let doubledArr = [];
  return func(num);
}

// 함수 doubleNum은 다른 함수를 인자로 받는 고차 함수입니다.
// 함수 doubleNum의 첫 번째 인자 func에 함수가 들어올 경우
// 함수 func는 함수 doubleNum의 콜백 함수입니다.
// 아래와 같은 경우, 함수 double은 함수 doubleNum의 콜백 함수입니다.
let output = doubleNum(double, 4);
console.log(output); // -> 8

2. 함수를 리턴하는 경우

function adder(added) {
  return function (num) {
    return num + added;
  };
}

함수 adder는 다른 함수를 리턴하는 고차 함수입니다.
adder는 인자 한 개를 입력받아서 함수(익명 함수)를 리턴합니다.
// 리턴되는 익명 함수는 인자 한 개를 받아서 added와 더한 값을 리턴합니다.

// adder(5)는 함수이므로 함수 호출 연산자 '()'를 사용할 수 있습니다.
let output = adder(5)(3); // -> 8
console.log(output); // -> 8

// adder가 리턴하는 함수를 변수에 저장할 수 있습니다.
// javascript에서 함수는 일급 객체이기 때문입니다.
const add3 = adder(3);
output = add3(2);
console.log(output); // -> 5

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

function double(num) {
  return num * 2;
}

function doubleAdder(added, func) {
  const doubled = func(added);
  return function (num) {
    return num + doubled;
  };
}

// 함수 doubleAdder는 고차 함수입니다.
// 함수 doubleAdder의 인자 func는 함수 doubleAdder의 콜백 함수 입니다.
// 함수 double은 함수 doubleAdder의 콜백으로 전달되었습니다.

// doubleAdder(5, double)는 함수이므로 함수 호출 기호 '()'를 사용할 수 있습니다.
doubleAdder(5, double)(3); // -> 13

// doubleAdder가 리턴하는 함수를 변수에 저장할 수 있습니다. (일급 객체)
const addTwice3 = doubleAdder(3, double);
addTwice3(2); // --> 8

내장 고차 함수 (Array)


  • filter() : filter 메서드는 주어진 함수의 테스트를 통과하는 모든 요소를 모아 새로운 배열로 반환함. 통과하는 요소가 없는 경우 빈 배열 반환.
    • callback함수true이면 요소를 새로운 배열에 추가, false면 버린다.
const words = ['spray', 'limit', 'elite', 'exuberant', 'destruction', 'present'];

const result = words.filter(word => word.length > 6);

console.log(result);
// expected output: Array ["exuberant", "destruction", "present"]

  • forEach() : forEach 메서드는 주어진 함수를 배열 요소 각각에 대해 실행
    • array.forEach(callback(value[,index[,array]]))
      • callback : 각 요소에 대해 실행할 함수
      • value : 처리할 현재 요소
      • index : 처리할 현재 요소의 인덱스
      • array : forEach()를 호출한

  • find() : find는 주어진 판별 함수를 만족하는 첫 번째 요소의 값을 반환, 해당 요소가 없다면 undefined를 반환

    • arr.find(callback)

    • callback 함수가 참을 반환 할 때까지 해당 배열의 각 요소에 대해서 callback 함수를 실행

    •  var inventory = [
       {name: 'apples', quantity: 2},
       {name: 'bananas', quantity: 0},
       {name: 'cherries', quantity: 5}
      	];
      
       function findCherries(fruit) { 
           return fruit.name === 'cherries';
       }
      
       console.log(inventory.find(findCherries)); 
      // { name: 					'cherries', quantity: 5 }

  • map() : map 메서드는 배열 내의 모든 요소 각각에 대하여 주어진 함수를 호출한 결과를 모아 새로운 배열 반환

    • 배열 요소 각각에 대응하는 결과값을 도출할 때 사용

    • callback 함수를 각각의 요소에 한번씩 순서대로 불러 그 함수의 반환값으로 새로운 배열을 만든다.

    • const array1 = [1, 4, 9, 16];
      
      // pass a function to map
      const map1 = array1.map(x => x * 2);
      
      console.log(map1);
      // expected output: Array [2, 8, 18, 32]
      			```
      

  • reduce() : reduce 메서드는 배열의 각 요소에 대해 주어진 리듀서 함수를 실행하고, 하나의 결과값을 반환한다.

    • 리듀서 함수는 1. 누산기 2. 현재 값 3. 현재 인덱스 4. 원본 배열을 인자로 가짐.

    • callback함수에서 initial value를 제공한다면 acc : initial value , index : 0 부터 시작

    • initail value를 제공하지 않는다면 acc : 첫 번째 value , index : 1 부터 시작

    • callback 함수에서 두 번째 인자에 '' , [] , 0 ... 중 넣은 타입에 따라 acc가 달라진다.

    • callback 함수 실행 결과 true인 경우 return acc을 한다면 reduce 함수 실행 후 결과값에 acc가 들어감. 이후 실행 결과 false가 나와서 return cur을 한 경우 결과값에 cur이 들어감.

    • const array1 = [1, 2, 3, 4];
      const reducer = (accumulator, currentValue) => accumulator + currentValue;
      
      // 1 + 2 + 3 + 4
      console.log(array1.reduce(reducer));
      // expected output: 10
      
      // 5 + 1 + 2 + 3 + 4
      console.log(array1.reduce(reducer, 5));
      // expected output: 15

  • sort() : 배열의 요소를 적절한 위치에 정렬한 후 정렬된 원본 배열을 반환한다. 기본 정렬 순서는 문자열의 유니코드를 따른다.
    • array.sort([compareFunction])
      • compareFunction 을 제공하지 않으면 문자열로 변환하고 유니코드를 따른다.
      • compareFunction 이 제공되면 배열 요소는 compare 함수의 반환 값에 따라 정렬
        • compareFunction(a, b)이 0보다 작은 경우 a를 b보다 낮은 색인으로 정렬합니다. 즉, a가 먼저옵니다.
        • compareFunction(a, b)이 0을 반환하면 a와 b를 서로에 대해 변경하지 않고 모든 다른 요소에 대해 정렬합니다.
        • compareFunction(a, b)이 0보다 큰 경우, b를 a보다 낮은 인덱스로 소트합니다.

  • some() : 배열 안의 어떤 요소라도 주어진 판별 함수를 통과하는지 테스트 , 빈 배열에서 호출하면 무조건 false 반환

    • some()callback 을 반환하는 요소를 찾을 때까지 배열에 있는 각 요소에 대해 한번씩 callback 함수를 실행함. 해당하는 요소를 발견한 경우 즉시 true반환 , 그렇지 않으면 false반환

    •     const array = [1, 2, 3, 4, 5];
      
      // checks whether an element is even
      const even = (element) => element % 2 === 0;
      
      console.log(array.some(even));
      // expected output: true```

  • every() : some()의 반대를 테스트하는 메서드, 빈 배열 호출 시 무조건 true 반환
    • every()callback이 거짓을 반환하는 요소를 찾을 때까지 배열에 있는 각 요소에 대해 한 번씩 callback 함수를 실행한다. 해당하는 요소를 발견한 경우 every는 즉시 false를 반환, 그렇지 않으면 true 반환
    • 			const isBelowThreshold = (currentValue) => currentValue < 40;
      			const array1 = [1, 30, 39, 29, 10, 13];
      			console.log(array1.every(isBelowThreshold));
      			// expected output: true
      			```
      
      

  • concat() : 인자로 주어진 배열이나 값들을 기존 배열에 합쳐서 새 배열을 반환한다.

    • array1.concat(array2);

    • 기존 배열을 변경하지 않는다.

    • 추가된 새로운 배열을 반환한다.

    • const array1 = ['a', 'b', 'c'];
      const array2 = ['d', 'e', 'f'];
      const array3 = array1.concat(array2);
      
      	console.log(array3);
      	expected output: Array ["a", "b", "c", "d", "e", "f"]

---

* ```flat()``` : 모든 하위 배열 요소를 지정한 깊이까지 재귀적으로 이어붙인 새로운 배열 생성 

	* ``` const newArr = arr.flat([depth])``` 
    * `depth` : 구조를 평탄화할 때 사용할 깊이 값, 기본값은 1
    * 반환 값 : 하위 배열을 이어붙인 새로운 배열
profile
즐거운 코딩

0개의 댓글