๐Ÿ’ป๐Ÿ’€/๊ฐœ๋ฐœ

[JS] ๊ณ ์ฐจ ํ•จ์ˆ˜(Higher-Order Function)

db2 2022. 7. 31. 22:42

๊ณ ์ฐจ ํ•จ์ˆ˜๋ž€

์•„๋ž˜ ์กฐ๊ฑด ์ค‘ ํ•˜๋‚˜ ์ด์ƒ์„ ๋งŒ์กฑํ•˜๋Š” ํ•จ์ˆ˜์ด๋‹ค.

  1. ํ•˜๋‚˜ ์ด์ƒ์˜ ํ•จ์ˆ˜๋ฅผ ์ธ์ž๋กœ ๋ฐ›๊ธฐ
  2. ๊ฒฐ๊ณผ๋กœ ํ•จ์ˆ˜ ๋ฐ˜ํ™˜ํ•˜๊ธฐ

์˜ˆ์ œ 1.

์กฐ๊ฑด 1, 2๋ฅผ ๋งŒ์กฑํ•˜๋Š” ๊ณ ์ฐจํ•จ์ˆ˜ ์˜ˆ์ œ์ด๋‹ค. ๊ณ ์ฐจํ•จ์ˆ˜ not์€ ์ธ์ž๋กœ ์ „๋‹ฌ๋ฐ›์€ ํ•จ์ˆ˜ f์˜ ์‹คํ–‰ ๊ฒฐ๊ณผ๊ฐ’์„ ๋ถ€์ •ํ•œ๋‹ค.

function not(f) {
  return function(...args) {
    let result = f.apply(this, args);
    return !result; // f์˜ ๊ฒฐ๊ณผ๋ฅผ ๋ถ€์ •ํ•œ๋‹ค.
  }
}

์ˆซ์ž๊ฐ€ ์ง์ˆ˜์ธ์ง€ ํŒ๋ณ„ํ•˜๋Š” ํ•จ์ˆ˜ isEven์„ ๊ณ ์ฐจํ•จ์ˆ˜ not์˜ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ „๋‹ฌํ•œ๋‹ค๋ฉด, ๊ทธ ๊ฒฐ๊ณผ๋Š” ์ˆซ์ž๊ฐ€ ํ™€์ˆ˜์ธ์ง€๋ฅผ ํŒ๋ณ„ํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์„ ๊ฒƒ์ด๋‹ค.

const isEven = x => x % 2 === 0;
const isOdd = not(isEven);

๋”ฐ๋ผ์„œ ๋ฐฐ์—ด์˜ ์š”์†Œ๋Š” ์ „๋ถ€ ํ™€์ˆ˜์ด๋ฏ€๋กœ ์•„๋ž˜ ์ฝ”๋“œ์˜ ๊ฒฐ๊ณผ๋Š” true๊ฐ€ ๋œ๋‹ค.

[1, 1, 3, 5, 5].every(isOdd); 

์˜ˆ์ œ 2.

JavaScript Array์˜ ๋‚ด์žฅ ๋ฉ”์„œ๋“œ forEach(), map(), filter() ๋“ฑ์€ ์กฐ๊ฑด 1์„ ๋งŒ์กฑํ•˜๋Š” ๋Œ€ํ‘œ์ ์ธ ๊ณ ์ฐจํ•จ์ˆ˜์ด๋‹ค. ์ฒซ ๋ฒˆ์งธ ์ธ์ž์— ๋ฐฐ์—ด์˜ ๊ฐ ์š”์†Œ๋ฅผ ์ธ์ž๋กœ ์ „๋‹ฌ๋ฐ›์•„ ์‹คํ–‰๋  ์ฝœ๋ฐฑ ํ•จ์ˆ˜๊ฐ€ ์ „๋‹ฌ๋˜์–ด์•ผ ํ•œ๋‹ค.

const nums = [1, 2, 3, 4];

// ์ต๋ช… ํ•จ์ˆ˜๋ฅผ ๊ณง๋ฐ”๋กœ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋‹ค. 
nums.forEach(num => console.log(num));

// ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋ฅผ ๋ถ„๋ฆฌํ•˜์—ฌ ์„ ์–ธํ•œ ๋’ค ์ „๋‹ฌํ•  ์ˆ˜๋„ ์žˆ๋‹ค. 
function log(num) {
    console.log(`Test Log: ${num}`);
}

name.forEach(log);

์ด ๋•Œ ๊ณ ์ฐจ ํ•จ์ˆ˜ forEach์˜ ๋‚ด๋ถ€ ๊ตฌํ˜„์„ ๋‚ด ๋ง˜๋Œ€๋กœ(?) ํ•ด๋ณด์•˜๋‹ค. ์ฐธ๊ณ ๋กœ ์ฝœ๋ฐฑ ํ•จ์ˆ˜ predicate์˜ ํ‘œ์ค€ ํƒ€์ž…์€ (value: T, index: number, array: readonly T[]) => void์ด๋‹ค. ์ฆ‰, ์ด 3๊ฐœ์˜ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๊ฐ€์ง€๋ฉฐ ์ฒซ ๋ฒˆ์งธ๋Š” ์ˆœํšŒ์ค‘์ธ ๋ฐฐ์—ด์˜ ์š”์†Œ, ๋‘ ๋ฒˆ์งธ๋Š” ์ˆœํšŒ์ค‘์ธ ๋ฐฐ์—ด ์š”์†Œ์˜ ์ธ๋ฑ์Šค, ์„ธ ๋ฒˆ์งธ๋Š” ์ˆœํšŒ์ค‘์ธ ๋ฐฐ์—ด์„ ์ „๋‹ฌ๋ฐ›๋Š”๋‹ค.

function forEach(predicate) {
    // this: forEach๋ฅผ ํ˜ธ์ถœํ•œ ๋ฐฐ์—ด
    for(let i = 0, len = this.length; i < len; i++) {
        predicate(this[i], i, this);
    }
}

filter() ๋ฉ”์„œ๋“œ๋Š” ์กฐ๊ฑด์— ๋งž๋Š” ์š”์†Œ๋งŒ ์ถ”์ถœํ•ด์„œ ์ƒˆ๋กœ์šด ๋ฐฐ์—ด์„ ๋งŒ๋“ค์–ด ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ณ ์ฐจํ•จ์ˆ˜์ด๋‹ค. ์œ„ ์˜ˆ์ œ 1์—์„œ ๋งŒ๋“  isEven ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด ์ง์ˆ˜์ธ ์š”์†Œ๋งŒ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ์ƒˆ ๋ฐฐ์—ด์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.

const nums = [1, 2, 3, 4];

const evenNums = nums.filter(isEven); // [2, 4]

// ๊ทธ๋ƒฅ ๋˜ ํ•œ ๋ฒˆ ๊ตฌํ˜„ํ•ด๋ณธ filter ๋ฉ”์„œ๋“œ
function filter(predicate) {
    const newArray = [];
    for(let i = 0, len = this.length; i < len; i++) {
        if(predicate(this[i], i, this)) {
            newArray.push(this[i]);
        }
    }
    return newArray;
}

์ฐธ๊ณ