콜백함수라고 부른다.커리함수라고 한다.자바스크립트에서 함수는 일급객체이다. 즉, 문자열, 숫자 같은 다른 데이터처럼 사용 가능하다.
함수 표현식과 선언식의 차이점은 호이스팅이다. 함수 표현식은 호이스팅이 적용되지 않는다. 호이스팅은 선언된 위치에 관계없이 어디서든 함수를 사용할 수 있도록 한다. 코드가 실행되는 과정에서 함수 선언부를 코드의 최상단으로 끌어올리는 것처럼 보이게 한다.
객체 안에 내장되어 있는 함수를 메소드라고 한다. 배열 안에 프로토타이프(원형객체)가 있고, 그 안에 메소드가 정의되어 있기 때문에, 배열 메소드를 사용할 수 있다.
함수를 인자로 받는 함수이거나 함수를 리턴하는 함수이거나 둘 다인 경우에도 고차함수이다.
자바스크립트에는 기본 내장된 고차함수가 여럿 있다. 배열 메소드 중 일부가 대표적인 고차함수에 해당한다.
배열의 각 요소가 특정 논리(함수)에 따르면, 사실(boolean)일 때 따로 분류(filter)한다.
function keep(arr, keeper) {
return arr.filter( el => { // 콜백 함수의 실행값이 true인 요소들로 새로운 배열을 리턴하는 filter 함수
return el === keeper; // boolean 값을 리턴하는 콜백 함수
})
}
=> 배열의 각 요소에 콜백 함수를 적용시켰을 때, true를 리턴하는 요소를 모아 새로운 배열을 리턴한다.
배열의 각 요소가 특정 논리(함수)에 의해 다른 요소로 지정(map) 된다.
function getLengthOfElements(arr) {
return arr.map( el => {
return el.length; // 배열의 각 요소의 길이를 구해 새로운 배열을 리턴한다.
})
}

조건문을 걸어줬을 때, 해당하지 않는 요소가 있는 경우에는 자동으로 undefined를 반환하게 된다.
배열의 각 요소를 특정 방법(함수)에 따라 원하는 하나의 형태로 응축한다. (reduction)
function computeProductOfAllElements(arr) {
return arr.reduce((acc, cur) => {
return acc * cur;
// acc = acc * cur;
// return acc; 이렇게 해도 맞게 되는 것 같다. 흠!
}, 1)
}

acc : 누적값. 초기값이 없으면 배열의 첫 번째 요소가 acc가 된다. cur : 현재 요소let = age = [3, 5, 2, 1, 7];
// 오름차순
age.sort((a, b) => a - b)
// 내림차순
age.sort((a, b) => b - a)
// objArr의 경우,
const student = [
{ name : "suri", age : 29},
{ name : "masuri", age : 25},
{ name : "hoon", age : 8},
{ name : "wook", age : 95}
]
// 오름차순
student.sort(function(a, b) {
return a.age - b.age;
}
// 내림차순
student.sort(function(a, b) {
return b.age - a.age;
}
forEach, find, filter, map, reduce, sort, some, every
// obj -> arr(이차원 배열)
export function objToArr(obj) {
let outerArr = [];
for (let key in obj) {
let innerArr = [];
innerArr.push(key, obj[key]);
outerArr.push(innerArr);
}
return outerArr;
}
// arr(이차원 배열) -> obj
export function arrToObj(arr) {
return arr.reduce((acc, cur) => {
return {
...acc,
[cur[0]] : cur[1]
}
}, {})
}
===비교===
export function objArrToArr(objArr, name){
objArr.reduce((acc, cur) => {
acc.push(cur.name)
return acc;
}, []);
}
// [obj, obj, obj] -> [arr, arr, arr]
export function objArrToArrArr(objArr) {
return objArr.map(el => {
let outerArr = [];
for (let key in el) {
let innerArr = [];
innerArr.push(key, el[key])
outerArr.push(innerArr);
}
return outerArr;
})
}
===비교 reduce 활용===
// [obj, obj, obj] -> [arr, arr, arr]
export function objArrToArrArr(objArr) {
return objArr.reduce((acc, cur) => {
let outerArr = [];
for (let key in cur) {
let innerArr = [];
innerArr.push(key, cur[key]);
outerArr.push(innerArr);
}
acc.push(outerArr);
return acc;
}, []);
}
추상화는 복잡한 어떤 것을 압축해서 핵심만 추출한 상태로 만드는 것이다. 추상화는 생산성을 향상시키는 이점이 있다.
값 수준에서의 추상화다.사고 수준에서의 추상화다. 
function functionParameter(func, num) {
return func(num);
}
function applyTwice(func, num) {
return func(func(num));
}
function compose(func1, func2, num) {
return func1(func2(num));
}
function compose2(func1, func2) {
return (number) => {
return func1(func2(number));
}
}
function pipe(...args) {
return (num) => {
let result = num;
for (let i = 0; i < args.length; i++) {
result = args[i](result);
}
return result;
}
}
function mapCallback(func, arr) {
let newArr = [];
for (let el of arr) {
newArr.push(func(el));
}
return newArr;
}
unction filterCallback(func, arr) {
let newArr = [];
for (let el of arr) {
if (func(el)) {
newArr.push(el);
}
}
return newArr;
}
return arr.filter(function (el) {
return el < num;
}).length;
[1, 2, 3].length // 3 결국 이것과 같다.
function lessThan100(number) {
return number < 100;
}
//...
return arr.filter(lessThan100)
function joinName(resultStr, user) {
return resultStr + user.name + ', ';
// resultStr = resultStr + user.name + ', ';
// return resultStr; 이렇게 두 가지 방법으로 표현이 가능하다.
}
let users = [
{ name: 'Tim', age: 40 },
{ name: 'Satya', age: 30 },
{ name: 'Sundar', age: 50 }
];
users.reduce(joinName, '');
'Tim, Satya, Sundar, '