우리가 살아가는 세상은 추상화로 가득 차있다. 추상화는 다른 말로 요약, 우리는 살아가며 사용하는 여러 물건들이나 시스템의 작동 방식을 알아야만 사용할수 있는 것이 아니다. 오히려 이런 세부 디테일을 알아야 할수록 세상은 너무나도 복잡해 질것이다. 따라서 우리는 사용하고 그 결과를 취하는 중간과정을 추상화, 즉 요약한다.
자바스크립트는 고차함수를 통해 이런 추상화를 도와준다. 우리는 원하는 결과를 얻기 위해 우리가 선언해준 각 변수들을 함수를 통해 변화시켜 결과를 얻는다. 이런 사고 과정을 추상화 해본다면, 우리는 변수를 통해 결과를 얻고 함수의 작동 방식은 추상화 하여 코드의 전체적인 모습을 쉽게 파악할 수 있게 된다.
자바스크립트에서 어떤 것들은 특별 대우를 받는다. 이런 것들을 일급 객체라 한다. 일급 객체는 다음과 같이 특별하게 취급된다.
자바스크립트에서 함수는 일급 객체로 취급된다. 이는 즉 함수를 변수에 할당할 수 있고(이는 함수 표현식을 보면 명확히 알 수 있다.) 함수는 다른 함수의 인자로 전달될 수 있으며, 함수는 다른 함수의 결과로서 리턴될 수 있다.
이때 함수를 인자로 받거나 함수를 리턴하는 함수를 고차 함수라 한다. 그리고 다른 함수의 인자(argument)로 전달되는 함수를 콜백 함수라 한다.
'함수를 리턴하는 함수'만을 일컫는 용어는 커리 함수라 한다. 커리 함수라는 용어를 사용할 경우 고차 함수는 '함수를 인자로 받는 함수'에만 한정지어 사용한다.
배열 메소드들 중 일부가 고차 함수에 해당된다. 자바스크립트에 기본적으로 내장(built-in) 되어 있기 때문에 내장 고차 함수라 말한다.
filter 메소드가 작동 하는 방식은 다음과 같다.
예를 들어서 숫자가 담겨 있는 배열이 있다고 가정하자. [1, 2, 3, 4, 5] 이중 짝수만 뽑아내고 싶으면 어떻게 해야 할까? filter메소드의 작동 방식을 따라가면, 배열의 각 요소(1, 2, 3...)가 짝수 라면(특정 기준) true(boolean) 그 수만 걸러서 다시 배열에 담는다(따로 분류).
const arr = [1, 2, 3, 4, 5, 6, 7];
const getEvenNumber = function(arr){
return arr.filter(function(el) {
return el % 2 === 0;
});
}
//getEvenNumber 함수는 filter(내장 고차 함수)를 리턴한다.
//filter 메소드의 인자는 함수 function(el)이다. 즉 고차 함수
//function(el)은 boolean을 return 받는다.
//fuction(el)의 리턴이 true 일경우 filter가 작동한다.
//el은 임의의 인자, for...in문에서 사용되는 것과 동일한 속성이다.
결과적으로 filter 메소드는 arr배열의 엘리먼트들을(el)돌며 function(el)이 실행되고, function(el)이 true일경우(el을 2로 나눴을때 나머지가 0이다 true or false?) 해당 el을 새로운 배열에 담는다.
map 메소드가 작동 하는 방식은 다음과 같다.
예를 들어서 숫자가 담겨져 있는 배열이라 하자. [1, 2, 3] 이 숫자들의 제곱으로 이루어진 새로운 배열을 만들고 싶으면 어떻게 해야 할까? map 메소드의 작동 방식을 따라가면, 배열의 각 요소(1, 2, 3)을 각각 제곱하여(특정 기준) 해당 숫자가 위치한 인덱스에 해당 숫자를 제곱한 값을 넣는다(다른 요소로 바뀐다).
const arr = [1, 2, 3];
const square = function(arr) {
return arr.map(function(el) {
return el * el;
});
} // square(arr) === [1, 4, 9]
//square 함수는 map(내장 고차 함수)를 리턴한다.
//map 메소드의 인자는 함수 function(el)이다. 즉 고차 함수
//function(el)은 el * el을 리턴한다.
//el은 임의의 인자, for...in문에서 사용되는 것과 동일한 속성이다.
결과적으로 map 메소드는 arr배열의 엘리먼트들을(el)돌며 function(el)이 실행되고, function(el)은 el * el을 리턴하며 해당 el을 el이 위치했던 인덱스와 같은 인덱스에 넣어 배열을 리턴한다.
reduce 메소드가 작동하는 방식은 다음과 같다.
예를 들어 숫자가 담겨져 있는 배열이라 하자. [1, 2, 3, 4 ,5] 이 숫자들의 평균을 구하고 싶으면 어떻게 해야 할까? reduce 메소드의 작동 방식을 따라가면, 배열의 각 요소(1, 2, 3...)를 합하고 인덱스 갯수 만큼 나눠주면(특정 압축 방법) 평균을 구할 수 있다(원하는 하나의 숫자).
const arr = [1, 2, 3, 4, 5];
const avarage = function(arr) {
return arr.reduce(function(acc, cur) {
return acc + cur
},0) / arr.length
}
//avarage 함수는 reduce(내장 고차 함수)를 리턴한다.
//reduce 메소드의 인자는 함수 function(acc, cur)이다. 즉 고차 함수
//function(acc, cur)은 arr의 모든 엘리먼트를 합산한다.
//최초값은 0으로 시작한다.
//avarage 함수의 리턴값은 reduce 결과값 나누기 원본 배열의 길이다.
결과적으로 reduce 메소드는 arr배열의 엘리먼트를 돌며 function(acc, cur)이 실행되는데 최초값이 0으로 주어졌으므로
reduce 메소드는 위와 같은 과정을 통해 arr의 엘리먼트 들을 총합 15라는 하나의 값으로 압축해 준다. 평균을 구하기 위해 압축된 값을 arr배열 길이만큼 나누고 리턴을 받는다.
앞으로 혼자 학습해볼 내용들!