일급 함수
는 리턴하는 값도 함수가 될 수도 있다.
일급 함수라고 하는 개념은 다양한 쓰임이 있고 용도, 테크닉 다양하다.
function ul(child: string): string {
return `<ul>${child}</ul>`;
}
function ol(child: string): string {
return `<ol>${child}</ol>`;
}
function makeLI(
container: (child: string) => string,
contents: string[]
): string {
const liList = [];
for (const content of contents) {
liList.push(`<li>${content}</li>`);
}
return container(liList.join(''));
}
const htmlUL = makeLI(ul,['월','화','수','목','금','토','일']);
const htmlOL = makeLI(ol, ['봄','여름','가을','겨울',]);
console.log(htmlUL);
console.log(htmlOL);
(출력)
<ul><li>월</li><li>화</li><li>수</li><li>목</li><li>금</li><li>토</li><li>일</li></ul>
<ul><ol>봄</ol><ol>여름</ol><ol>가을</ol><ol>겨울</ol></ul>
1. ul과 ol이라고 하는 함수는 child 인자를 받고 string을 리턴한다.
2. ul과 ol은 html 태그 형태의 문자열로 감싸진 문자열을 string을 리턴한다.
3. makeLI 함수명을 갖고 있는 인자가 두 개이다.
container
는 문자열 타입의 child
인자를 받고 string
을 리턴하는 함수 타입이다.contents
는 문자열 배열이다.4. makeLI
함수는 빈 배열 하나를 상수로 만들었다. const liList = [ ];
5. for of
문을 돌면서 contents 인자가 문자열 배열로 들어온다. contents를 하나씩 빼오고, liList 빈 배열에 push
해서 데이터를 추가한다.
6. content의 배열로 들어온 li 태그로 감싸진 문자열로 변경돼서 liList 배열에 계속 쌓인다.
7. cotainer 함수를 호출하고, 인자로 liList 배열을 join
합친 다음에 container한테 넘겨주고 container가 리턴한 값을 다시 리턴한다.
8. makeLI에 ul,ol은 호출하는 게 아니라 값으로써 함수 그 자체를 넘겨준다.
const htmlUL = makeLI(ul,['월','화','수','목','금','토','일']);
처음 호출되는 함수는 makeLI다. makeLI로 들어가 보자!
const liList = [ ];
여기서 container 함수를 인자로 받고 contents 배열에서 하나씩 빼서 liList에 차곡차곡 쌓인다.
liList에 li로 감싸져있는 월, 화, 수, 목, 금, 토, 일을 볼 수 있다.
container 함수는 ul 함수를 호출하고 있다. 즉, li로 감싸져 있는 요일 목록을 문자열로 넘겨준다.
return <ul>${child}</ul>;
이 부분을 실행해 보면 ul 함수로 li 태그로 감싸져있는 요일 목록이 들어왔다.
아직 makeLI가 리턴된 게 아니다!
return container(liList.join(''));
container가 리턴 한 값을 가지고 리턴한다. 최종적으로 ol, ul 만들어지는 형태가 된다.
여기서 누가 호출되는지가 핵심이다.
makeLI
라는 함수는 온전히 li과 ol에만 집중을 하고 나머지 것에는 신경을 쓰지 않는다.
이것을 함수를 인자로 넘겨줄 수 있기 때문에 가능한 프로그래밍 테크닉이다.
function SalePrice(discountRate, price) {
return price - (price * (discountRate * 0,01));
}
console.log('여름세일 - ' + salePrice(30, 567000)); '여름 세일 - 396900'
console.log('겨울세일 - ' + salePrice(10, 567000)); '겨울 세일 - 510300'
function discountPrice(discountRate) {
return function(price){
return price - (price * (discountRate * 0,01));
}
}
console.log('여름세일 - ' + salePrice(30, 567000)); '여름 세일 - 396900'
console.log('겨울세일 - ' + salePrice(10, 567000)); '겨울 세일 - 510300'
let summerPrice = discountPrice(30);
let winterPrice = discountPrice(10);
console.log('여름세일 - ' + salePrice(30, 567000)); '여름 세일 - 396900'
console.log('겨울세일 - ' + salePrice(10, 567000)); '겨울 세일 - 510300'
1. SalePrice
와 discountPrice
같지만 discountPrice는 바로 함수를 리턴한다.
이것을 리턴 값이 함수인 경우이다.
2. discountPrice는 첫 번째 함수를 리턴한다. 함수가 리턴되고 discountRate는 30을 준다.
salePrice와 동일하다.
3. 결과적으로 똑같은데 첫 번째 함수를 리턴하니까 다시 또 호출해서 원가를 넘겨줘야 되는 아주 복잡한 동작을 수행한다. 이 부분을 응용 해보자!
4. 첫 번째 인자가 함수로 반환된다. 그 함수 자체도 값으로써 취급해서 잠깐 변수에 담았다가 호출한다.
5. 각각 변수에 이름을 주고 변수에 담았다가 호출을 한다.
let summerPrice = discountPrice(30);
let winterPrice = discountPrice(10);
6. 이렇게 하는 이유는? 여름 세일과 겨울 세일의 레이블을 다 삭제해 보자!
그러면 어떤 부분이 여름 세일 가인지 겨울 세일 가인지 변수에서 확인 할 수 있다.
단지 변수에 한번 넣었을 뿐 변수에 이름을 지어주고 의미를 부여해서 표현력을 극대화한다.
이것을 함수를 합성한다 혹은 함수를 만든다고 하는 테크닉으로 부르기도 한다.