[Effective JavaScript] 고차 함수에 익숙해지자

김범식·2023년 6월 29일
0

Effective JavaScript

목록 보기
7/33
post-thumbnail

고차함수란?


함수를 인자로 받거나 함수를 반환하는 함수

  1. 콜백 함수 : 다른 함수의 인자로 전달되어 특정 동작이나 로직을 수행하는 함수
  2. 함수 커링(Curring) : 여러개의 인자를 받는 함수를 인자 하나만 받는 함수의체인으로 바꾸는것
  3. 함수 합성(Composition) : 두 개 이상의 함수를 조합하여 새로운 함수를 새성하는 것



콜백함수 예시

function processArray(arr, callback) {
  for (var i = 0; i < arr.length; i++) {
    callback(arr[i]);
  }
}

function printElement(el) {
  console.log(el);
}

var numbers = [1, 2, 3, 4, 5];
processArray(numbers, printElement);
// 출력:
// 1
// 2
// 3
// 4
// 5

자바스크립트에서 함수는 일급 객체이기 때문에 매개변수처럼 사용할 수 있다.



함수 커링 예시

function add(a) {
  return function(b) {
    return a + b;
  };
}

var add5 = add(5);
console.log(add5(3)); // 출력: 8



함수 합성 예시

// 함수 합성 예시
function multiplyBy2(x) {
  return x * 2;
}

function add1(x) {
  return x + 1;
}

var composedFunction = function(x) {
  return add1(multiplyBy2(x));
};

console.log(composedFunction(3)); // 출력: 7



고차 함수에 익숙해지자


Sort()

앞서 살펴본 고차함수를 잘 이용하면 코드가 더 간단하고 명료해진다. 고차 함수는 다른 함수를 인자로 받거나 그 결과로 함수를 반환하는 함수이다. 배열의 표준 정렬 메서드 sort() 를 생각해보자

function compareNumbers(x,y){
	if( x < y ){
		return -1;
	}
	if(x > y ){
		return 1; 
	}
	return 0;
}

	

[3,2,1,4,6,5].sort(compareNumbers); // [1,2,3,4,5,6]

호출자로 부터(여기서는 배열) 비교 메서드를 가지는 객체를 전달받기를 요구하지만, 하나의 메서드만 필요하기 때문에 함수를 직접 받는것이 더 간결하다.

이 예제는 익명함수를 통해 더 간단하게 만들 수 있다.

[3,2,1,4,6,5].sort(function(x,y)=>{
	if( x < y ){
		return -1;
	}
	if(x > y ){
		return 1; 
	}
	return 0;
}); // [1,2,3,4,5,6]

고차 함수를 사용하면 이처럼 코드를 간결하게 만들 수 있다.



map()

일반적인 반복문으로 작성한 코드는 다음과 같다.

var name = ["Fred","Wilma","Pebbles"];
var upper = [];
for(var i = 0 ; i <name.length;i<++){
	upper[i] = names[i].toUpperCase();
}

upper; // ["FRED","WILMA","PEBBLES"]

map()메서드를 사용한 코드

var name = ["Fred","Wilma","Pebbles"];
var upper = name.map(function(name){
	return name.toUpperCase();
})

upper; // ["FRED","WILMA","PEBBLES"]

반복문의 세부 사항을 완전히 제거하고 각요소의 변환을 지역함수내에서 구현만 하면 된다!



직접 생성


고차 함수의 사용에 익숙해지고 나면, 직접 작성할 기회도 생길 것이다. 비슷하거나 중복된 코드를 자주 보게 된다면 이는 숨길 수 없는 고차함수 추상의 신호이다.



  1. 알파벳을 순서대로 나열한 문자열 생성코드
var aIndex = "a".charCodeAt(0); //97
var alphabet = "";
for(var i = 0;i<26;i++){
	alpabet += String.fromCharCode(aIndex+i);
}

alphabet; // abcdefghijklmnopqrstuvwxyz



  1. 숫자를 포함한 문자열
var digits = "";
for(var i = 0;i<10;i++){
	digits += i; //문자열에 숫자를 더하면 문자가 됨
}

digits // "0123456789"



  1. 임의의 글자로 만드는 문자열
var random = "";
for(var i = 0;i<8;i++){
	random += String.fromCharCode(Math.floor(Math.random()*26)+aIndex);
}

random; //"enslxifh" (매번 다른결과 반환)

이 예제들은 서로다른 문자열을 반환하지만 공통된 로직을 소유하고 있다. 이제 공통 부분을 추출하고 유틸리티 함수로 옮기면 다음과 같은 코드를 만들 수 있다.

//추상화된 고차함수

function buildString(n, callback){
	var result ="";
	for(var i = 0;i<n;i++){
		result += callback(i);	
}



구현


해당 공통로직을 사용하면 이전의 세 예제를 다음과 같이 간단하게 구현할 수 있다.

var alphabet = buildString(26, function(i){
	return String.fromCharCode(aIndex+i);
})

alphabet; // abcdefghijklmnopqrstuvwxyz
var disits = buildString(10, function(i){
	return i;
})

digits // "0123456789"
var random = builderString(8, function(){
	return String.fromCharCode(Math.floor(Math.random()*26+aIndex));
})

random; //"enslxifh" (매번 다른결과 반환)

고차함수추상을 생성하는 방식은 장점이 많다.

  • 구현시 반복문 경계부분의 상태를 올바르게 지정하기 어렵다면 고차함수로 작성
  • 버그를 수정할 때 프로그램 전체를 수정하는대신 단 한 번만 수정하면 됨
  • 추상의 이름을 builderString 과 같이 명백하게 지정해주면 코드를 읽는 사람이 최신 사항까지 알 필요가 없다.



기억할 점

  • 고차 함수는 다른 함수를 인자로 받거나 그 결과로 함수를 반환하는 함수이다.
  • 이미 존재하는 라이브러리에 포함된 고차함수의 사용에 익숙해지자
  • 고차 함수로 대체할 수 있는 공통 코딩 패턴을 찾는 방법을 익히자
profile
frontend developer

0개의 댓글