📖 [강의 내용 및 개념 정리]
목차
일급 객체에 대해 설명하기에 앞서 비행기 좌석의 first class 또는 first class citizen 에 비유를 들곤 한다.
이 비유에 대해 "조건을 갖춘 first class는 권한과 자유도가 높다"는 것을 비유적으로 표현했다고 받아들였다.
일급 객체에 대한 정의를 살펴보면 다음과 같다.
컴퓨터 프로그래밍 언어 디자인에서, 일급객체란 다른 객체들에 일반적으로 적용 가능한 연산을 모두 지원하는 객체를 가리킨다. 보통 함수에 인자로 넘기기, 수정하기, 변수에 대입하기와 같은 연산을 지원할 때 일급 객체라고 한다. (출처: 위키백과)
일급 객체: first-class citizens (first-class type, first-class object, first-class value)
일급 객체에 대한 역사적 배경을 간단히 소개한 글이 있어 인용해 보았다.
출처: medium - Javascript에서 왜 함수가 1급 객체일까요?
1급 객체, 2급 객체에 대한 개념은 1960년대에 Christopher Strachey에 의해 소개 되었고, 사실상 그 용어를 명시적으로 정의한 것은 아니지만 Algol 라는 프로그래밍 언어의 실수(Real number)와 프로시저를 비교함으로써 1급 객체의 개념에 대해 처음으로 언급하였다고 합니다. 1990년대에는 미국의 컴퓨터 과학자 Raphael Finkel 이 2급, 3급 객체에 대한 정의를 제안했는데, 널리 받아 들여지고 있지 않은 상황이라고 해요.
자바스크립트에서는 "함수"가 일급 객체에 해당한다.
add
라는 변수에 함수를 할당한 예시const add = function (num1, num2) {
return num1 + num2;
}
callback
함수를 실행하고, false일 경우 두번째 전달인자인 errorCallback
함수를 실행하는 예시const example = (callback, errorCallback) => {
const criteria = true;
if (isTrue) {
callback();
return;
}
errorCallback();
}
function sum(a, b) {
return a + b;
}
function currySum(a) {
return function(b) {
return a + b;
};
}
console.log(sum(10, 20) === currySum(10)(20))
고차함수(higher order function): 함수를 전달인자로 받을 수 있고, 함수를 리턴할 수 있는 함수
콜백함수(callback function): 다른 함수(caller)의 전달인자로 전달되는 함수
어떤 작업이 완료되었을 때 호출하는 경우가 많아 답신 전화를 뜻하는 콜백함수라는 이름이 붙여짐
문제) 함수들을 입력받아 함수들이 입력된 차례대로 결합된 새로운 함수를 리턴해야 합니다.
인자 1 : func1
number 타입을 입력받아 number 타입을 리턴하는 함수
인자 2 : func2
number 타입을 입력받아 number 타입을 리턴하는 함수
인자 N : funcN
number 타입을 입력받아 임의의 타입을 리턴하는 함수
출력
함수를 리턴해야 합니다.
리턴되는 함수는 정수를 입력받아 func1, func2, ..., funcN의 순으로 적용합니다.
입출력 예시
function square(num) {
return num * num;
}
function add5(num) {
return num + 5;
}
let output = pipe(add5, square);
console.log(output(4)); // --> 81
풀이
function pipe(...args) {
// TODO: 여기에 코드를 작성합니다.
return function(num) {
return args.reduce((result, curFn) => {
return curFn(result);
}, num)
}
}
배열을 하나의 값으로 만들어줌
const result =
arr.reduce((accumulator, currentValue) => {
// reduce에서 실행할 함수 내용
}, initialValue)
const users = ['kim', 'park', 'lee'];
let usersNameStr = '';
const result = users.reduce((acc, cur) => {
usersNameStr += `${cur}, `;
return usersNameStr;
}, '')
console.log(result); // 'kim, park, lee'
function makeAddressBook(addressBook, user) {
let firstLetter = user.name[0];
if(firstLetter in addressBook) {
addressBook[firstLetter].push(user);
} else {
addressBook[firstLetter] = [];
addressBook[firstLetter].push(user);
}
return addressBook;
}
let users = [
{ name: 'Tim', age: 40 },
{ name: 'Satya', age: 30 },
{ name: 'Sundar', age: 50 }
];
const result = users.reduce(makeAddressBook, {});
console.log(result);
/**
* {
* S: [{ name: 'Satya', age: 30 }, { name: 'Sundar', age: 50 }],
* T: [{ name: 'Tim', age: 40 }],
* }
*/
추상화: 컴퓨터 과학에서 추상화(abstraction)는 복잡한 자료, 모듈, 시스템 등으로부터 핵심적인 개념 또는 기능을 간추려 내는 것을 말한다.
프로그램을 작성할 때, 자주 반복해서 사용하는 로직은 별도의 함수로 작성하기도 합니다. 이 역시 추상화의 좋은 사례입니다. 추상화의 관점에서 함수를 바라보면, 함수는 사고(thought) 또는 논리(logic)의 묶음입니다.
- 함수 = 값을 전달받아 값을 리턴한다. = 값에 대한 복잡한 로직은 감추어져 있다. = 값 수준에서의 추상화
- 값 수준의 추상화: 단순히 값(value)을 전달받아 처리하는 수준
- 고차 함수 = 함수를 전달받거나 함수를 리턴한다. = 사고(함수)에 대한 복잡한 로직은 감추어져 있다. = 사고 수준에서의 추상화
- 사고의 추상화: 함수(사고의 묶음)를 전달받아 처리하는 수준
function compose(...funcArgs) {
// compose는 여러 개의 함수를 인자로 전달받아 함수를 리턴하는 고차 함수입니다.
// compose가 리턴하는 함수(익명 함수)는 임의의 타입의 data를 입력받아,
return function (data) {
// funcArgs의 요소인 함수들을 차례대로 적용(apply)시킨 결과를 리턴합니다.
let result = data;
for (let i = 0; i < funcArgs.length; i++) {
result = funcArgs[i](result);
}
return result;
};
}
// compose를 통해 함수들이 순서대로 적용된다는 것이 직관적으로 드러납니다.
// 각각의 함수는 다른 목적을 위해 재사용(reuse) 될 수 있습니다.
const getAverageAgeOfMale = compose(
getOnlyMales, // 배열을 입력받아 배열을 리턴하는 함수
getOnlyAges, // 배열을 입력받아 배열을 리턴하는 함수
getAverage // 배열을 입력받아 `number` 타입을 리턴하는 함수
);
const result = getAverageAgeOfMale(data);
console.log(result); // --> 26
어제 Unit1을 마무리하며 회고의 글을 적었다.
목표와 잘한 부분, 아쉬운 부분 그리고 앞으로의 약속(Action Item)에 대한 회고였다.
Action Item 중 하나는 "배운 개념에 대해 하루에 한가지 이상 '왜'라는 질문하기"였다.
목표로 설정한 이유에 대해 다음과 같이 부연설명을 붙였는데 많은 분들이 공감해주시고 응원해주셨다.
얕은 복사와 깊은 복사에 대해 배우고, 개발자인 친구에게 이 내용에 대해 공유 했을 때
”자바스크립트에는 깊은 복사를 하는 내장 함수(기능)가 왜 없을까?”라는 질문을 들은 적이 있습니다.
그 때, 망치로 한대 맞은 듯 ‘왜 나는 이런 질문을 하지 못했을까…’ 하고 생각했습니다.
그 후 medium - 깊은 복사와 얕은 복사에 대한 심도있는 이야기 이 아티클을 통해 답변을 얻을 수 있었고
얕은 복사와 깊은 복사의 차이, 상황에 따라 어떤 복사를 선택해야 할지 한번 더 생각해 볼 수 있는 시간이 되었습니다.
학습과정은 더딜 수 있지만 항상 “왜?”라는 질문과 함께 답변을 찾아가는 연습을 하다보면
앞으로 성장하는 개발자가 될 수 있을거라 생각하게 되었습니다.
그래서 오늘의 "왜?"는 "커링함수를 왜 쓸까?"이고 이 내용을 자바스크립트 시리즈에 정리하고자 한다.