함수를 인자(argument)로 받을 수 있고, 함수의 형태로 리턴할 수 있는 함수
자바스크립트에서 특별한 대우를 받는 객체
대표적인 일급 객체 중 하나가 함수입니다.
(자바스크립트가 나온 시점을 고려했을 때,) 자바스크립트에서 함수는 아래와 같이 특별하게 취급됩니다.
함수를 변수에 할당할 수 있기 때문에,
함수를 배열의 요소나 객체의 속성값으로 저장할 수 있습니다.
이는 함수를 데이터(string, number, boolean, array, object)를 다루듯이 다룰 수 있다는 걸 의미합니다.
/*
* 아래는 변수 square에 함수를 할당하는 함수 표현식입니다.
* 자바스크립트에서 함수는 일급 객체이기 때문에 변수에 저장할 수 있습니다.
*
* 함수 표현식은 할당 전에 사용할 수 없습니다.
* square(7); // --> ReferenceError: Can't find variable: square
*/
const square = function (num) {
return num * num;
};
// square에는 함수가 저장되어 있으므로 (일급 객체), 함수 호출 연산자 '()'를 사용할 수 있습니다.
output = square(7);
console.log(output); // --> 49
함수 표현식
은 변수에 할당한 다음 사용할 수 있습니다.
함수 표현식(function expression)은 호이스팅(Hoisting)
이 적용되지 않기 때문입니다.
함수 선언식의 호이스팅에 지나치게 의존하면, 코드의 유지 보수가 쉽지 않습니다.
코드 리뷰나 디버깅을 할 때, 코드를 위아래로 왔다 갔다 하게 될 수 있습니다.
함수 선언식은 어느 위치에나 함수를 선언할 수 있고, 함수의 실행 위치도 중요하지 않습니다.
반면에 함수 표현식은 함수의 할당과 실행의 위치에 따라 결과가 달라지기 때문에, 코드의 위치를 어느 정도 예측할 수 있습니다.
호이스팅을 제외하면, 함수 선언식과 함수 표현식은 크게 차이가 없습니다.
다만, 함수 표현식의 경우는 함수가 변수에 저장될 수 있다는 사실을 보다 분명하게 보여 줍니다.
함수는 변수에 저장된 데이터를 인자로 받거나, 리턴 값으로 사용할 수 있습니다.
함수도 변수에 저장될 수 있기 때문에 함수를 인자로 받거나, 리턴 값으로 사용할 수 있습니다.
함수를 인자argument
로 받을 수 있고, 함수의 형태로 리턴할 수 있는 함수
다른 함수caller
의 인자argument
로 전달되는 함수
함수를 인자로 받는 함수
function triple(num) {
return num * 3;
}
function tripleNum(func, num) { // tripleNum: 다른 함수(func)를 인자로 받는 고차함수
return func(num); // func: 콜백함수
}
console.log(tripleNum(triple, 3)); // 9
// 함수 triple은 고차함수 tripleNum의 콜백함수
function add(num){ // add: 다른 익명함수를 리턴하는 고차함수
return function (num2) { // 익명함수: 콜백함수
return num + num2;
}
}
add(2)(3) // add(2)는 함수임으로 ();를 함수 호출 연산자 ();를 사용할 수 있음
// 5
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
모든 요소에게 동일한 행동을 준 값에 대하여 모두 반환하는 메소드
행동은 내가 직접 작성해야 하며, 함수
로 작성하여 인자로 넣음
기존 배열을 수정하지 않음
// let으로 선언된 배열 arr에 대하여
let arr = [1, 2, 3]
// map 메소드를 이용하여 모든 요소에게 동일하게 3을 곱해준 값을 반환하는 새로운 배열을 변수 result에 담는다.
let result = arr.map((el) => el * 3)
// result를 반환한다.
return result;
모든 요소 중 내가 원하는 값만 필터링하여 반환하는 메소드
행동은 내가 직접 작성해야 하며, 함수
로 작성하여 인자로 넣음
기존 배열을 수정하지 않음
// let으로 선언된 배열 arr에 대하여
let arr = [1, 2, 3]
// filter 메소드를 이용하여 모든 요소 중 짝수인 값만 필터링하여 반환하는 새로운 배열을 변수 result에 담는다.
let result = arr.filter((el) => el % 2 === 0);
// result를 반환한다.
return result
배열을 하나의 값으로 만들어주는 메소드
배열의 각 요소를
특정 방법(함수)에 따라
원하는 하나의 형태로
응축합니다. (reduction)
배열의 첫 번째 인덱스인 요소
가 '초기값'이 된다.
초기값은 누적값(acc)
의 기반이 된다.
그 다음 요소부터 현재값(cur)
이 된다.
'누적값'과 '현재값'은 우리가 원하는 행동에 의하여 누적값에 저장된다.
이 과정을 배열의 마지막 인덱스 요소까지 반복한다.
마지막 누적값(acc)
을 반환
// let으로 선언된 배열 arr에 대하여
let arr = [1, 2, 3]
// reduce 메소드를 이용하여 원하는 행동에 의하여 누적값을 저장하는 과정을 배열의 길이만큼 반복하여 새로운 변수 result에 할당한다.
let result = arr.reduce((acc, cur, idx) => {
acc + cur;
return acc;
}
// result를 반환한다.
return result
forEach
, find
, filter
, map
, reduce
, sort
, some
, every
filter 메소드에 들어가는 콜백 함수는 truthy 또는 falsy를 리턴할 수 있습니다.
그러나 filter 메소드에 들어가는 콜백 함수는 Deep equality를 통해 조건을 명확하게 밝히는 걸 권장합니다.
따라서 콜백 함수가 내부 조건에 따라 참(true) 또는 거짓(false)을 리턴하도록 구현하길 권장합니다.
복잡한 어떤 것을 압축해서 핵심만 추출한 상태로 만드는 것
(생산성의 향상)
단순히 값(value)을 전달받아 처리하는 수준
함수 === 값을 전달받아 값을 리턴한다 === 값에 대한 복잡한 로직은 감추어져 있다 ===
값 수준에서의 추상화
사고의 추상화: 함수(사고의 묶음)를 전달받아 처리하는 수준