728x90
고차함수란?
- 고차 함수는 함수 인수를 받거나 함수를 반환하는 함수입니다. ( === 함수를 주고받는 함수)
- map(),reduce(),filter(),setTimeout(),addEventListener(),bind() ….
// ES6 version
const characters = [
{name: 'Luke Skywalker', img: 'http://example.com/img/luke.jpg', species: 'human'},
{name: 'Han Solo', img: 'http://example.com/img/han.jpg', species: 'human'},
{name: 'Leia Organa', img: 'http://example.com/img/leia.jpg', species: 'human'},
{name: 'Chewbacca', img: 'http://example.com/img/chewie.jpg', species: 'wookie'}
];
const humans = data => data.filter(character => character.species === 'human');
const images = data => data.map(character => character.img);
const compose = (func1, func2) => data => func2(func1(data));
const displayCharacterImages = compose(humans, images);
console.log(displayCharacterImages(characters));
/*
Logs out the following array
["http://example.com/img/luke.jpg",
"http://example.com/img/han.jpg",
"http://example.com/img/leia.jpg"
]
*/
- 함수의 빌딩블록을 최대한 기능단위로 잘게 쪼개면 테스트와 유지보수 비용을 줄이고 재사용성을 높일 수 있다.
고차함수의 변수
함수 또한 변수이다.
- 함수는 특별한 변수입니다. 값을 다시 할당하여 다른 함수에 매개변수로 전달할 수 있습니다. (콜백 인자로 전달되는 비동기 함수를 작성하는데 유용합니다.)
변수의 스코프
- 함수 외부에서 정의 된 변수는 해당 함수로 접근 할 수 있습니다. 그것들은 함수 자체뿐만 아니라 그 함수 외부에서 수정 될 수 있습니다.
- 함수 내부에 정의 된 변수와 함수에 전달 된 이자는 함수 내에서만 접근이 가능합니다.
변수를 함수에 전달
- 변수가 함수에 인자로 전달되면 변수 값이 인자 안에 복사가 됩니다.
일급 클래스 함수
- 자바스크립트가 함수를 일급 시민으로 취급한다고 들었을 것입니다. 이것이 의미하는 것은 자바스크립트의 함수가 객체로 취급된다는 것입니다. 자바스크립트는 객체 타입을 가지고, 변수의 값으로 할당될 수 있으며, 다른 참조 변수처럼 전달되고 반환될 수 있습니다.
- 1급 객체의 조건
- 변수나 데이타에 할당 할 수 있어야 한다.
- 객체의 인자로 넘길 수 있어야 한다.
- 객체의 리턴값으로 리턴 할수 있어야 한다.
Filter, Map, Reduce의 사용
- Filter,Map,Reduce는 모두 함수가 인수로 전달될 수 있다. 즉 고차함수다.
- 일반적인 방법으로 써진 코드보다 반복을 줄이고 개선할 수 있다. 많이 활용하자
- forEach()는 side-effect가 생성되어 undefined가 반환될 수가 있다. 함수형 프로그래밍을 하려한다면 지양하자.대신 이 세 함수를 사용하자!
예시
18세 이하의 사람들을 걸러내기 위해 .filter()를 사용하는 것에 대해 이야기했습니다. coffeeLover property을 추가하는 .map()과 reduce()를 합쳐서 마침내 모든 사람의 나이를 합한 합계를 만듭니다. 실제로 이 세 단계를 결합한 코드를 작성해 봅시다.
const people = [
{ name: ‘John Doe’, age: 16 },
{ name: ‘Thomas Calls’, age: 19 },
{ name: ‘Liam Smith’, age: 20 },
{ name: ‘Jessy Pinkman’, age: 18 }
];
const coffeeLovers = [‘John Doe’, ‘Liam Smith’, ‘Jessy Pinkman’];
const ageAbove18 = (person) => person.age >= 18;
const addCoffeeLoverProperty = (person) => {
person.coffeeLover = coffeeLovers.includes(person.name);
return person;
}
const ageReducer = (sum, person) => { return sum + person.age;}, 0);
const coffeeLoversAbove18 = people.filter(ageAbove18).map(addCoffeeLoverProperty);
const totalAgeOfCoffeeLoversAbove18 = coffeeLoversAbove18.reduce(ageReducer);
const totalAge = people.reduce(ageReducer);
예시2
cents를 나타내는 정수 값을 화폐로 형식화하는 작업이 있다고 가정하십시오. 요청에는 통화 기호 지정 및 소수 구분 기호와 같은 일부 사용자 정의가 포함됩니다.
formatCurrency 는 고정 통화 기호와 소수점 구분 기호가 있는 함수를 반환합니다.
const formatCurrency = function(
currencySymbol,
decimalSeparator ) {
return function( value ) {
const wholePart = Math.trunc( value / 100 );
let fractionalPart = value % 100;
if ( fractionalPart < 10 ) {
fractionalPart = '0' + fractionalPart;
}
return `${currencySymbol}${wholePart}${decimalSeparator}${fractionalPart}`;
}
}
> getLabel = formatCurrency( '$', '.' );
> getLabel( 1999 )
"$19.99"
> getLabel( 2499 )
"$24.99"
비구조화 할당 ...
- 비구조화 할당(destructuring assignment) 구문은 배열이나 객체의 속성을 해체하여 그 값을 개별 변수에 담을 수 있게 하는 자바스크립트 표현식(expression)
배열
[a1, a2, ...rest_a] = [1, 2, 3, 4, 5, 6, 7, 8, 9];
console.log(a1); // 1
console.log(a2); // 2
console.log(rest_a); // [3, 4, 5, 6, 7, 8, 9]
- 좌항이 호출될 변수명 집합, 우항이 할당할 값 입니다.또한 전개 연산자( … )를 사용하여 좌항에서 명시적으로 할당되지 않은 나머지 배열 값들을 사용할 수 있습니다.
- 좌항의 각 요소에는 같은 index를 가지는 배열값이 할당됩니다.
[a1, a2, ...rest_a, a3] = [1, 2, 3, 4, 5, 6, 7, 8, 9]; // error
[a1, a2, ...rest_a] = {a1 : 10, a2: 20}; // error
- 전개 연산자 이후에 변수를 입력하거나, 좌 우항이 다른 속성일 경우 에러가 발생합니다.
객체
var { a1, a2, ...rest_a } = { a1 : 10, a2 : 20, a3 : 30, a4 : 40 };
console.log(a1); // 10
console.log(a2); // 20
console.log(rest_a); // { a3: 30, a4: 40 }
- 객체의 경우에는 우항의 key 값이 좌항의 변수명과 매칭됩니다.
- 배열과 마찬가지로 var, let, const가 적용 가능합니다.
- 또한 우항의 key값에 변수명으로 사용 불가능한 문자열이 있을경우 아래와 같은 방식으로 비구조화 할 수 있습니다.
var key = 'it is key';
var { 'an-apple':an_apple, [key]:it_is_key } = { 'an-apple' : 10, 'it is key' : 20};
console.log(an_apple); // 10
console.log(it_is_key); // 20
- 다만 이 경우에는 ‘an-apple’과 매칭할 변수명(an_apple)을 작성하지 않으면 에러가 발생하게 됩니다.
- 마지막으로 객체 비구조화에서 주의해야 할 점은 변수 선언에 대한 명시(var, let, const)가 없을 경우 괄호를 사용하여 묶어주어야 한다는 것 입니다.
({ a, b } = { a : 10, b : 20});
console.log(a); // 10
console.log(b); // 20
{ c, d } = { c : 30, d : 40}; // error
함수에서 사용
함수의 파라미터 부분에서도 비구조화 할당을 사용할 수 있습니다.
이러한 문법은 특히 API 응답 값을 처리하는데에 유용하게 사용됩니다.
function renderUser({name, age, addr}){
console.log(name);
console.log(age);
console.log(addr);
}
const users = [
{name: 'kim', age: 10, addr:'kor'},
{name: 'joe', age: 20, addr:'usa'},
{name: 'miko', age: 30, addr:'jp'}
];
users.map((user) => {
renderUser(user);
});
마찬가지로 map함수의 파라미터에도 바로 사용할 수 있습니다.
const users = [
{name: 'kim', age: 10, addr:'kor'},
{name: 'joe', age: 20, addr:'usa'},
{name: 'miko', age: 30, addr:'jp'}
];
users.map(({name, age, addr}) => {
console.log(name);
console.log(age);
console.log(addr);
});
for of 문
뿐만 아니라 배열 내 객체들은 for of 문을 사용하여 비구조화 할 수 있습니다.
const users = [
{name: 'kim', age: 10, addr:'kor'},
{name: 'joe', age: 20, addr:'usa'},
{name: 'miko', age: 30, addr:'jp'}
];
for(var {name : n, age : a} of users){
console.log(n);
console.log(a);
}
중첩된 객체 및 배열의 비구조화
중첩된 객체 및 배열 역시 비구조화 할 수 있습니다.
const kim = {
name: 'kim',
age: 10,
addr: 'kor',
friends: [
{name: 'joe', age: 20, addr:'usa'},
{name: 'miko', age: 30, addr:'jp'}
]
};
var { name: userName, friends: [ ,{ name: jpFriend }] } = kim;
console.log(userName); // kim
console.log(jpFriend); // miko
friends 배열의 호출 변수를 명시하는 대신, 배열을 한번 더 비구조화한다.
참고 및 추가공부
728x90
'Programming Language' 카테고리의 다른 글
JS33 - 24.컬렉션과 생성기(Collection and Constructor) (0) | 2021.06.23 |
---|---|
JS33 - 23.재귀함수(Recursive Function) (0) | 2021.06.08 |
JS33 - 21.클로져(Closure) (0) | 2021.06.08 |
[번역]Currying in Javascript 자바스크립트 커링 (0) | 2021.06.03 |
JS33 - 20.Pure function, Side effect, Mutate (0) | 2021.06.03 |
댓글