๐ Chapter 7: ํจ์ํ ์ต์ ํ
๐ ํจ์ ์คํ์ ๋ด๋ถ ์๋ ์๋ฆฌโ
- ์๋ฐ์คํฌ๋ฆฝํธ์์๋ ํจ์๋ฅผ ํธ์ถํ ๋๋ง๋ค ํจ์ ์ฝํ ์คํธ ์คํ์ ๋ ์ฝ๋(ํ๋ ์) ๊ฐ ์์ฑ๋๋ค.
- ์ฝํ ์คํธ ์คํ์ ํจ์ ์คํ ๋ฐ ํจ์๊ฐ ์์์ผ(ํด๋ก์ ๊ฐ์ ๊ฒ) ๋ณ์๋ฅผ ๊ด๋ฆฌํ๋ ์๋ฐ์คํฌ๋ฆฝํธ ํ๋ก๊ทธ๋๋ฐ ๋ชจ๋ธ์ด๋ค.
- ์คํ์ ์ธ์ ๋ ์ ์ญ ๋ฐ์ดํฐ๊ฐ ๋ด๊ธด, ์ ์ญ ์คํ ์ฝํ ์คํธ ํ๋ ์์์ ์์ํ๋ค.
- ์ ์ญ ์ฝํ ์คํธ ํ๋ ์์ ํญ์ ์คํ ๋งจ ๋ฐ์ ์์นํ๋ค. ์ง์ญ ๋ณ์๊ฐ ํ๋๋ ์๋ ๋น ํ๋ ์์ 48๋นํธ ์ ๋ ๋๊ณ , ์ซ์, ๋ถ๋ฆฌ์ธ ๊ฐ์ ์ง์ญ ๋ณ์/๋งค๊ฐ๋ณ์๋ 8๋ฐ์ดํธ๋ฅผ ์ฐจ์งํ๋ค.
executionContextData = {
scopeChain, // ์ด ํจ์์ variableObject, ๊ทธ๋ฆฌ๊ณ ๋ถ๋ชจ ์คํ ์ฝํ
์คํธ์ variableObject์ ์ ๊ทผํ๋ ์ฐ๊ฒฐ ๊ณ ๋ฆฌ์ด๋ค.
variableObject, // ํจ์์ ์ธ์, ๋ด๋ถ ๋ณ์, ํจ์ ์ ์ธ๋ถ๋ฅผ ํฌํจํ๋ค.
this // ํจ์ ๊ฐ์ฒด๋ฅผ ๊ฐ๋ฆฌํค๋ ๋ ํผ๋ฐ์ค
}
variableObject
๋ ์ง์ญ ๋ณ์์ ํจ์๋ ๋ฌผ๋ก , ํจ์์ ์ธ์, ์ ์ฌ๋ฐฐ์ด ๊ฐ์ฒดarguments
๋ฅผ ๊ฐ๋ฆฌํค๋ ์์ฑ์ด๋ฏ๋ก, ์ฌ์ค์ ์คํ ํ๋ ์์ ํฌ๊ธฐ๋ ์ด ์์ฑ์ผ๋ก ๊ฒฐ์ ๋๋ค.- ์ค์ฝํ ์ฒด์ธ์ ์ด ํจ์์ ์ฝํ ์คํธ๋ฅผ ๊ทธ ๋ถ๋ชจ ์คํ ์ฝํ ์คํธ์ ์ฐ๊ฒฐํ๊ฑฐ๋ ์ฐธ์กฐํ๋ค.
- ๋ชจ๋ ํจ์๋ ์ค์ฝํ ์ฒด์ธ์ด ๊ฒฐ๊ตญ ์ง/๊ฐ์ ์ ์ผ๋ก ์ ์ญ ์ฝํ ์คํธ์ ์ฐ๊ฒฐ๋๋ค.
- ๐ ์คํ์ ์ฃผ์ ์๋ ๊ท์น
- ์๋ฐํฌ๋ฆฝํธ๋ ๋จ์ผ ์ค๋ ๋๋ก ์๋ํ๋ค. ์ฆ, ๋๊ธฐ ์คํ ๋ฐฉ์์ด๋ค.
- ์ ์ญ ์ฝํ ์คํธ๋ ๋จ ํ๋๋ง ์กด์ฌํ๋ค. (๋ชจ๋ ํจ์ ์ฝํ ์คํธ๋ ์ ์ญ ์ฝํ ์คํธ๋ฅผ ๊ณต์ ํ๋ค.)
- ํจ์ ์ฝํ ์คํธ ๊ฐ์๋ ์ ํ์ ์๋ค.
- ํจ์๊ฐ ํธ์ถํ ๋๋ง๋ค ์คํ ์ฝํ ์คํธ๊ฐ ์๋ก ์์ฑ๋๋ฉฐ, ์๊ธฐ ์์ ์ ์ฌ๊ท ํธ์ถํ ๋๋ ๋ง์ฐฌ๊ฐ์ง์ด๋ค.
- ํจ์ํ ํ๋ก๊ทธ๋๋ฐ์ ํจ์๋ฅผ ์ต๋ํ ์ฌ์ฉํ๋ ค๊ณ ํ๋ฏ๋ก, ์ ์ฐ์ฑ๊ณผ ์ฌ์ฌ์ฉ์ ๋๋ฆฌ๊ณ ์ ๋น๋ฉดํ ๋ฌธ์ ๋ฅผ ๊ฐ๋ฅํ ํ ๋ง์ ํจ์๋ก ๋ถํดํ๊ณ ์ปค๋ฆฌํ๋ ๊ฑด ์ผ๋ง๋ ์ง ์ข์ง๋ง, ์ปค๋ฆฌ๋ ํจ์๋ฅผ ์ง๋์น๊ฒ ์ฌ์ฉํ๋ฉด ์ฝํ ์คํธ ์คํ์ ์ด๋ค ์์ผ๋ก๋ ์ํฅ์ ๋ผ์น๋ค.
๐ ์ปค๋ง๊ณผ ํจ์ ์ฝํ ์คํธ ์คํโ
- ์ถ์ํ๋ฅผ ํ ๊บผํ ๋ ์ ํ๋ฉด ์ผ๋ฐ์ ์ธ ํจ์ ํ๊ฐ๋ณด๋ค ์ฝํ ์คํธ ์ค๋ฒํด๋๊ฐ ๋ ๋ง์ด ๋ฐ์ํ ์ ์๋ค.
const logger = function(appender, layout, layout, name, level, message);
// ...
const logger =
function (appender) {
return function (layout) {
return function (name) {
return function (level) {
return function (message) {
// ...
}
}
}
}
}
- ์์ ๊ฐ์ ์ค์ฒฉ ๊ตฌ์กฐ๋ ํ ๋ฒ์ ํธ์ถํ๋ ๊ฒ ๋ณด๋ค ํจ์ ์คํ์ ๋ ๋ง์ด ์ด๋ค.
logger
ํจ์๋ฅผ ์ปค๋ง ์์ด ์คํํ๋ฉด ์๋ฐ์คํฌ๋ฆฝํธ๋ ๋๊ธฐ ์คํ๋๊ธฐ ๋๋ฌธ์ ์ฐ์ ์ ์ญ ์ฝํ ์คํธ ์คํ์ ์ ์ ๋ฉ์ถ๊ณ ์ ํ์ฑ ์ฝํ ์คํธ๋ฅผ ๋ง๋ ๋ค์, ๋ณ์ ํด์์ ์ฌ์ฉํ ์ ์ญ ์ฝํ ์คํธ ๋ ํผ๋ฐ์ค๋ฅผ ์์ฑํ๋ค.logger
ํจ์๋ ๊ทธ ์์์ ๋ค๋ฅธLog4js
์ฐ์ฐ์ ํธ์ถํ๋ฏ๋ก ์ ํจ์ ์ฝํ ์คํธ๊ฐ ์์ฑ๋์ด ์คํ์ ์์ธ๋ค. ์๋ฐ์คํฌ๋ฆฝํธ ํด๋ก์ ๋๋ฌธ์ ๋ด๋ถ ํจ์ ํธ์ถ๋ก ๋น๋กฏ๋ ํจ์ ์ฝํ ์คํธ๋ ๋ค๋ฅธ ์ฝํ ์คํธ ์์ ์ฐจ๊ณก์ฐจ๊ณก ์์ด๋ฉฐ, ๊ฐ ์ฝํ ์คํธ๋ ์ผ์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ฐจ์งํ ์ฑscopeChain
๋ ํผ๋ฐ์ค๋ฅผ ํตํด ์ฐ๊ฒฐ๋๋ค.- ์ค์ฒฉ ํจ์๋ฅผ ์คํํ๋ฉด ์ด๋ฐ ์์ผ๋ก ํจ์ ์ฝํ ์คํธ๊ฐ ์ฆ๊ฐํ๊ณ , ํจ์๋ง๋ค ์คํ ํ๋ ์์ด ์๋ก ์๊ธฐ๋ฏ๋ก ํจ์๊ฐ ์ค์ฒฉ๋ ์ ๋ณด๋งํผ ์คํ์ด ์ปค์ง๋ค. ์ปค๋ง๊ณผ ์ฌ๊ท๋ ํจ์ ํธ์ถ์ ์ค์ฒฉํ์ฌ ์๋ํ๋ค.
- ๋ค์ ์คํ์ด ์์๋๋ก ์คํ์ด ์๋ฃ๋๋ฉด ๋ฐํ์์ ๋ค์ ์ฒ์ ์ํ๋ก ๋์๊ฐ๊ณ ์ ์ญ ์ฝํ ์คํธ ๋จ ํ๋๋ง ์คํ ์ํ๋ก ๋จ๋๋ค. ์ด๊ฒ์ด ์๋ฐ์คํฌ๋ฆฝํธ ํด๋ก์ ๋ผ๋ ๊ฒ์ด๋ค.
- ๋ชจ๋ ํจ์๋ฅผ ์ปค๋ฆฌํ๋ฉด ํญ์ ์ข์ ๊ฒ ๊ฐ์ง๋ง, ๊ณผ์ฉํ๋ฉด ์์ฒญ๋ ๋ฉ๋ชจ๋ฆฌ๊ฐ ์๋ชจ๋๋ฉด์ ํ๋ก๊ทธ๋จ ์คํ ์๋๊ฐ ํ์ ํ ๋จ์ด์ง ์ ์๋ค.
const add = function (a, b) {
return a + b;
};
const c_add = curry2(add);
const input = _.range(80000);
addAll(input, add); // -> 511993600000000
addAll(input, c_add); // -> ๋ธ๋ผ์ฐ์ ๊ฐ ๋ป์
function addAll(arr, fn) {
let result = 0;
for(let i = 0; i < arr.length; i++) {
for(let j = 0; j < arr.length; j++) {
result += fn(arr[i], arr[j]);
}
}
return result;
}
๐ ์ฌ๊ท ์ฝ๋์ ๋ฌธ์ ์ โ
- ํจ์๊ฐ ์์ ์ ํธ์ถํ ๋์๋ ์ ํจ์ ์ฝํ ์คํธ๊ฐ ๋ง๋ค์ด์ง๋ค.
- ์์ฒญ ํฐ ์ฉ๋์ ๋ฐ์ดํฐ๋ฅผ ์ฌ๊ท๋ก ์ฒ๋ฆฌํ ๋์๋ ๋ฐฐ์ด ํฌ๊ธฐ๋งํผ ์คํ์ด ์ปค์ง ์ ์๋ค.
- ๋ฆฌ์คํธ, ํนํ ์์๊ฐ ์์ฃผ ๋ง์ ๋ฆฌ์คํธ๋
map
,filter
,reduce
๋ฑ์ ๊ณ ๊ณํจ์๋ฅผ ์ด์ฉํด์ ํ์ํ๋ ๋ฐฉ๋ฒ์ด ์ข๋ค. ์ด๋ฐ ํจ์๋ฅผ ์ฐ๋ฉด ํจ์ ํธ์ถ์ ์ค์ฒฉํ์ง ์๊ณ ๋ฐ๋ณตํ ๋๋ง๋ค ์คํ์ ๊ณ์ ์ฌํ์ฉํ ์ ์๋ค.
๐ ๋๊ธํ ํ๊ฐ๋ก ์คํ์ ๋ฆ์ถคโ
- ๋ถํ์ํ ํจ์ ํธ์ถ์ ์ผ๊ฐ๊ณ ๊ผญ ํ์ํ ์ ๋ ฅ๋ง ๋ฃ๊ณ ์คํํ๋ฉด ์ฌ๋ฌ๋ชจ๋ก ์ฑ๋ฅ ํฅ์์ ๊ธฐ๋ํ ์ ์๋ค.
- ํ์ค์ผ ๊ฐ์ ํจ์ํ ์ธ์ด๋ ๊ธฐ๋ณธ์ ์ผ๋ก ๋ชจ๋ ํจ์ ํ๊ฐ์์ ๋๊ธํ๊ฒ ํ๊ฐ(lazy function evaluation) ํ๋๋ก ์ง์ํ๋ค.
- ๋๊ธํ ํ๊ฐ๋ ์ฌ๋ฌ ๊ฐ์ง ์ ๋ต์ด ์์ง๋ง, ๊ฐ๋ฅํ ํ ์ค๋, ์์กดํ๋ ํํ์์ด ํธ์ถ๋ ๋๊น์ง ๋ฏธ๋ฃฌ๋ค๋ ๊ทผ๋ณธ ์ฌ์์ ๊ฐ๋ค.
- ์๋ฐ์คํฌ๋ฆฝํธ๋ ๊ธฐ๋ณธ์ ์ผ๋ก ํจ์ ๊ฒฐ๊ด๊ฐ์ด ํ์ํ์ง ๋ฐ์ ธ๋ณผ ์๋ ์์ด ๋ณ์์ ๋ฐ์ธ๋ฉ๋์๋ง์ ํํ์ ํ๊ฐ๋ฅผ ๋ง์น๋ค. ๊ทธ๋์ ํ์์ค๋ฐ ํ๊ฐ๋ผ๊ณ ํ๋ค.
- ๋ค์ Maybe ๋ชจ๋๋ ์์ ์ด๋ค.
// Maybe ๋ชจ๋๋
Maybe.of(student).getOrElse(createNewStudent());
// ์๋์ ๊ฐ์ด ์คํ๋ ๊ฑฐ ๊ฐ์ง๋ง ์๋ฐ์คํฌ๋ฆฝํธ ์์ง์ ๊ทธ๋ ์ง ์๋ค.
if(!student) {
return createNewStudent();
}
else {
return student;
}
- ์๋ฐ์คํฌ๋ฆฝํธ ์์ง์ ์กฐ๊ธํ๊ฒ ํ๊ฐํ๋ฏ๋ก ํ์ ๊ฐ์ฒด๊ฐ
null
์ด๋ ์๋๋createNewStudent
ํจ์๋ฅผ ๋ฌด์กฐ๊ฑด ์คํํ๋ค. - ๋๊ธํ๊ฒ ํ๊ฐํ๋ฉด, ํํ์์ ์ ์ฝ๋์ฒ๋ผ ์๋ํ๊ฒ ์ง๋ง ํ์ ๊ฐ์ฒด๊ฐ ์ ์์ด ์๋ ๊ฒฝ์ฐ
createNewStudent
ํจ์๋ ํธ์ถํ์ง ์๋๋ค. - ๋๊ธํ ํ๊ฐ๋ ์ด๋ป๊ฒ ํ์ฉํ ์ ์์๊น?
- ๋ถํ์ํ ๊ณ์ฐ์ ํผํ๋ค.
- ํจ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์์ ๋จ์ถ ์ตํฉ(shortcut fusion)์ ์ฌ์ฉํ๋ค.
๐ ๋์ฒด ํจ์ํ ์กฐํฉ์ผ๋ก ๊ณ์ฐ์ ํํผโ
- ๊ฐ์ฅ ๋จ์ํ ์ฉ๋ก๋ ํจ์๋ฅผ ๋ ํผ๋ฐ์ค๋ก ์ ๋ฌํ๊ณ ์กฐ๊ฑด์ ๋ฐ๋ผ ํ์ชฝ๋ง ํธ์ถํ์ฌ ์ธ๋ฐ์๋ ๊ณ์ฐ์ ๊ฑด๋๋ฐ๋ ๊ฒ์ด๋ค.
const alt = R.curry((func1 , func2, val) => func1(val) || func2(val));
const showStudent = R.compose(append('#student-info'),
alt(findStudent, createNewStudent)); // ํจ์๋ฅผ ์กฐ๊ธํ๊ฒ ํธ์ถํ์ง ์๊ณ , ํจ์๋ฅผ ๋ ํผ๋ฐ์ค๋ก ์ ๋ฌํ๊ณ ์กฐํฉ๊ธฐ๊ฐ ์คํ์ ์กฐ์ ํ๋ค.
showStudent('444-44-4444');
- ํจ์ ์กฐํฉ๊ธฐ๊ฐ ์์์ ํจ์ ํธ์ถ์ ๊ด์ฅํ๊ธฐ ๋๋ฌธ์ ์ด ์ฝ๋๋ ๋ค์ ๋ช ๋ นํ ์ฝ๋์ ๋๊ฐ์ด ์๋ํ๋ค.
var student = findStudent('444-44-4444');
if(student !== null) {
append('#student-info', student);
}
else {
append('#student-info', createNewStudent('444-44-4444'));
}
๐ ๋จ์ถ ์ตํฉ์ ํ์ฉโ
- ๋ค์์ ๋ก๋์ JS๋ฅผ ์ฌ์ฉํ ๊ฑฐ์ฃผ ๊ตญ๊ฐ๋ณ ์ธ์์์ ๋ฐ๋ผ ์ ๋ ฌํ ๋ฆฌ์คํธ๋ฅผ ๋ง๋๋ ์ฝ๋์ด๋ค.
_.chain([p1, p2, p3, p4, p5, p6, p7])
.filter(isValid)
.map(_.property('address.country')).reduce(gatherStats, {})
.values()
.sortBy('count')
.reverse()
.first()
.value()
- ์ด์ฒ๋ผ ์ ์ธ์ ์ธ ํํ๋ก ํ๋ก๊ทธ๋จ์ ์์ฑํ๋ ๊ฑด, ํ๊ณ ์ถ์ ์ผ์ ๋ฏธ๋ฆฌ ์ ์ํจ์ผ๋ก์จ ํจ์๊ฐ ์ด๋ป๊ฒ ์๋ํ๋ ์ ๊ฒฝ ์ฐ์ง ์๊ณ ๋ฌด์จ ์ผ์ ํด์ผ ํ๋์ง๋ง ๋ฐํ๋ค๋ ์๋ฏธ์ด๋ค.
- ๋๋ถ์ ๋จ์ถ ์ตํฉ์ด๋ผ๋ ๊ธฐ๋ฒ์ผ๋ก ๋ก๋์ JS๊ฐ ํ๋ก๊ทธ๋จ ์คํ์ ๋ด๋ถ์ ์ผ๋ก ์ต์ ํํ ์ ์๋ค.
- ๋จ์ถ ์ตํฉ์ ๋ช ๊ฐ ํจ์์ ์คํ์ ํ๋๋ก ๋ณํฉํ๊ณ ์ค๊ฐ ๊ฒฐ๊ณผ๋ฅผ ๊ณ์ฐํ ๋ ์ฌ์ฉํ๋ ๋ด๋ถ ์๋ฃ๊ตฌ์กฐ์ ๊ฐ์๋ฅผ ์ค์ด๋ ํจ์ ์์ค์ ์ต์ ํ์ด๋ค.
- ์๋ฃ๊ตฌ์กฐ๊ฐ ์ค๋ฉด ๋๋ ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ ๋ ํ์ํ ๊ณผ๋ํ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ์ ๋ฎ์ถ ์ ์๋ค.
- ๋ค์์ ๋ก๋์ JS์ ๋๊ธํ ํ๊ฐ ๋ฐ ๋จ์ถ ์ตํฉ์ ์ฌ์ฉํ ๊ฒ์ด๋ค.
const square = (x) => Math.pow(x, 2);
const isEven = (x) => x % 2 === 0;
const numbers = _.range(200); // 1 ~ 200 ์ฌ์ด์ ์ซ์๋ก ๊ตฌ์ฑ๋ ๋ฐฐ์ด์ ์์ฑ
const result =
_.chain(numbers)
.map(square)
.filter(isEven)
.take(3) // filter ๊ธฐ์ค์ผ๋ก ๋ง์กฑํ๋ ์ฒ์ ์ธ ์ซ์๋ง ์ฒ๋ฆฌํ๋ค.
.value(); // [0, 4, 16]
result.length; // 5
๐ 'ํ์ํ ๋ ๋ถ๋ฅด๋ฆฌ' ์ ๋ตโ
- ๋ฐ๋ณต์ ์ธ ๊ณ์ฐ์ ํผํ๋ ๊ฒ๋ ์ ํ๋ฆฌ์ผ์ด์ ์คํ ์๋๋ฅผ ๋์ด์ฌ๋ฆฌ๋ ๋ฐฉ๋ฒ์ผ๋ก ์บ์๋ฅผ ์ฌ์ฉํ์๋ค.
- ๋ค์์ ํจ์์ ์บ์ ๊ณ์ธต์ ๊ฐ๋จํ ๊ตฌํํ ์ฝ๋์ด๋ค.
function cachedFn (cache, fn, args) {
// ํจ์ ์คํ ๊ฒฐ๊ณผ๋ฅผ ์๋ณํ๊ธฐ ์ํด ํจ์๋ช
๊ณผ ์ธ์๋ฅผ ์กฐํฉํ์ฌ ํค๊ฐ์ ์ ํ๋ค.
let key = fn.name + JSON.stringify(args);
if (contains(cache, key)) {
return get(cache, key);
}
else {
let result = fn.apply(this, args); // ์บ์์ ๊ฐ์ด ์์ผ๋ฉด ํจ์๋ฅผ ์คํํ๋ค. (์บ์ ๋ฏธ์ค)
put(cache, key, result); // ๊ฒฐ๊ณผ๋ฅผ ์บ์์ ๋ด๋๋ค.
return result;
}
}
findStudent
ํจ์ ์คํ์cachedFn
์ผ๋ก ๊ฐ์ธ๋ฉด ๋ค์๊ณผ ๊ฐ๋ค.
var cache = {};
cachedFn(cache, findStudent, '444-44-4444'); // ์ฒ์์๋ ์บ์ ๋ฏธ์ค์ด๋ฏ๋ก findStudent๋ฅผ ์คํ
cachedFn(cache, findStudent, '444-44-4444'); // ๋ ๋ฒ์งธ๋ ์บ์์ ๋ณด๊ด๋ ๊ฐ์ ๊ณง๋ฐ๋ก ์ฝ๋๋ค.
- ํ์ง๋ง ์ด๋ฐ ํจ์์ ์ผ์ผ์ด ์ด๋ฐ ๋ํผ๋ฅผ ๋๊ณ ํธ์ถํ๊ฒ๋ ์ฝ๋ฉํ๋ ๊ฑด ์๋นํ ๋ฒ๊ฒ๊ธฐ๋ ํ๊ณ ๊ฐ๋ ์ฑ์ด ๋จ์ด์ง๊ณ , ๊ทธ๋ ๊ฒ ์์ฑํ ํจ์๋ ์ ์ญ ๊ณต์ ์บ์ ๊ฐ์ฒด์ ์์กดํ๋ ๋ถ์ํจ๊ณผ๊ฐ ์๋ค.
- ๊ทธ๋ ๊ธฐ ๋๋ฌธ์ ํจ์ํ ์ธ์ด์๋ ๋ฉ๋ชจํ(memoization) ๋ผ๋ ๋ฉ์ปค๋์ฆ์ด ์๋ค.
๐ ๋ฉ๋ชจํโ
- ํจ์์ ๊ฒฐ๊ณผ๋ฅผ ํด๋น ์ ๋ ฅ๊ณผ ์ฐ๊ด์ํค๋ ์ผ, ์ฆ ๋ค์ ๋งํด, ํจ์์ ์ ๋ ฅ์ ์ด๋ค ๊ฐ์ผ๋ก ๊ณ์ฐํด๋ด๋ ๊ฑด ์ด๋ค ํจ์ํ ํ๋ก๊ทธ๋๋ฐ์ ์๋ฆฌ ๋๋ถ์ ๊ฐ๋ฅํ ๊น? ๊ทธ๋ ๋ค. ๋ฐ๋ก ์ฐธ์กฐ ํฌ๋ช ์ฑ์ด๋ค.
๐ ๊ณ์ฐ๋์ด ๋ง์ ํจ์๋ฅผ ๋ฉ๋ชจํโ
- ์์ ํจ์ํ ์ธ์ด๋ ์๋์ผ๋ก ๋ฉ๋ชจํ๋ฅผ ์ค์ฒํ์ง๋ง, ์๋ฐ์คํฌ๋ฆฝํธ๋ ํ์ด์ฌ ๊ฐ์ ์ธ์ด์์๋ ํจ์๋ฅผ ์ธ์ ๋ฉ๋ชจ ํ ์ง ์ ํํ ์ ์๋๋ฐ, ์๋ฅผ ๋ค์ด ๋ฌธ์์ด ROT13 ํ์์ผ๋ก ์ธ์ฝ๋ฉํ๋ rot13 ํจ์๋ฅผ ๋ณด์.
var discountCode = 'functional_js_50_off';
rot13(discountCode); // shapgvbany_wf_50_bss
- ์ฌ๊ธฐ์ ์ค์ํ ์ ์ rot13 ํจ์์ ๋์ผํ ๋ฌธ์์ด์ ์ ๋ ฅํ๋ฉด ๋ฐ๋์ ๋์ผํ ๋ฌธ์์ด์ด ์ถ๋ ฅ๋๋ค (์ฆ, ์ฐธ์กฐ ํฌ๋ช ํ๋ค)๋ ์ฌ์ค์ด๋ค.
- ๋ฐ๊ฟ ๋งํด, ์ด ํจ์๋ฅผ ๋ฉ๋ชจํ๋ฉด ์์ฒญ๋ ์ฑ๋ฅ ํฅ์์ ๊ธฐ๋ํ ์ ์๋ค.
- ๋ฉ๋ชจํ๋ฅผ ํ๋ฉด ๋์ผํ ์ ๋ ฅ์ผ๋ก ํจ์๋ฅผ ์ฌํธ์ถํ ๋ ๋ด๋ถ ์บ์๊ฐ ํํธ๋์ด ์ฆ์ ๊ฒฐ๊ณผ๊ฐ ๋ฐํ๋๋ค.
- ์๋ฐ์คํฌ๋ฆฝํธ์ ๊ณ ์ ๋ฐ ์๊ฐ API๊ฐ ๊ทธ ์์ด๋ค. ์ด API๋
Date.now()
,console.time()
๊ฐ์ ๊ธฐ๋ณธ ์๋ฐ์คํฌ๋ฆฝํธ ํจ์๋ณด๋ค ๋ ์ ํํ ํ์์คํฌํ๋ฅผ ๊ณ์ฐํ๊ณ ํจ์ ํธ์ถ ๊ฒฝ๊ณผ ์๊ฐ์ ์ด ์ ์๋ค. - ์๊ฐ์ ์ฌ๋ ํธ์ถ์ tap์ผ๋ก ์ถ๊ฐ
const start = () => now();
const runs = [];
const end = function (start) {
let end = now();
let result = (end - start).toFixed(3);
runs.push(result);
return result;
};
const test = function (fn, input) {
return () => fn(input);
};
const testRot13 = IO.form(start)
// tap ์กฐํฉ๊ธฐ๋ก ๋ชจ๋๋๋ฅผ ํตํด ์์ ์๊ฐ ์ ๋ณด๋ฅผ ์ ํํ๋ค.
.map(R.tap(test(rot13, 'functional_js_50_off')))
.map(end);
testRot13.run();
testRot13.run();
assert.ok(runs[0] >= runs[1]);
- ํจ์ ํธ์ถ์ ๋ฉ๋ชจํ ์ถ๊ฐ
Function.prototype.memoized = function() {
let key = JSON.stringify(arguments);
// ๋ด๋ถ ์ง์ญ ์บ์๋ฅผ ๋ง๋ ๋ค.
this._cache = this._cache || {};
// ์ด์ ์ ํจ์๋ฅผ ์คํํ ์ ์๋์ง ์บ์๋ฅผ ๋จผ์ ์ฝ๊ณ ๊ฐ์ด ์์ผ๋ฉด ํจ์๋ฅผ ๊ฑด๋๋ฐ๊ณ
// ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํ๋ฉฐ, ๊ฐ์ด ์์ผ๋ฉด ๊ณ์ฐ์ ํ๋ค.
this._cache[key] = this._cache[key] ||
this.apply(this, arguments);
return this._cache[key];
};
// ํจ์ ๋ฉ๋ชจํ๋ฅผ ํ์ฑํํ๋ค.
Function.prototype.memoize = function() {
let fn = this;
is(fn.length === 0 || fn.length > 1) {
return fn; // ๋จํญ ํจ์๋ง ๋ฉ๋ชจํ๋ค.
}
return function () {
// ํจ์ ์ธ์คํด์ค๋ฅผ memoized ํจ์๋ก ๊ฐ์ผ๋ค.
return fn.memoized.apply(fn, arguments);
}
}
- ์์ ๊ฐ์ด
Function
๊ฐ์ฒด๋ฅผ ํ์ฅํ๋ ์ด๋์๊ฑด ๋ฉ๋ชจํ ๊ธฐ๋ฅ์ ๊บผ๋ด ์ธ ์ ์๊ณ ์ ์ญ ๊ณต์ ์บ์์ ์ ๊ทผํ๋ ๊ธฐ์์ ์ธ ๋ถ์ํจ๊ณผ๊ฐ ์ฌ๋ผ์ก๋ค. - ๋ ํจ์์ ๋ด๋ถ ์บ์ ์ฒด์ ๋ฅผ ์ถ์ํ์ฌ ํ ์คํธ์ ์์ ํ ๋ฌด๊ดํ ์ฝ๋๋ก ๋ง๋ค์๋ค.
- ์ฌ๋ฌ ์ธ์๋ฅผ ๋ฐ๋ ํจ์์ ๋ฉ๋ชจํ ๊ณผ์ ์๋ ์๋ฌด๋๋ ์ ํฉํ ์บ์ํค๋ฅผ ์์ฑํ๋ ์์ ์ด ๋ณต์กํ๊ณ ๋น์ผ ์ฐ์ฐ์ ์๋ฐํ๊ฒ ๋๊ธฐ ๋๋ฌธ์ ์ด๋ด ๋ ์ปค๋ง์ ์ฌ์ฉํ๋ค.
๐ ์ปค๋ง๊ณผ ๋ฉ๋ชจํ๋ฅผ ํ์ฉโ
- ๋ณต์กํ ํจ์, ์ฆ ์ธ์๊ฐ ์ฌ๋ฌ ๊ฐ์ธ ํจ์๋ ์๋ฌด๋ฆฌ ์์ํจ์๋ผ ํด๋ ์บ์ํ๊ธฐ๊ฐ ์ด๋ ต๋ค.
- ํ ๊ฐ์ง ํด๊ฒฐ ๋ฐฉ๋ฒ์ ์ปค๋ง์ด๋ค.
// ์ด ํจ์๋ ์ฐธ์กฐ ํฌ๋ช
ํ์ง ์์ง๋ง, ์ค์ ๋ก ๊ฐ๋น์ผ ๊ฒ์์ด๋ ์๊ฒฉ HTTP ์์ฒญ์ ํ ๋๋ ๋ณดํต ๊ฒฐ๊ณผ๋ฅผ ์บ์ํ๋ ๊ฒฝ์ฐ๊ฐ ๋ง๋ค.
const safeFindObject = R.curry(function (db, ssn) {
// ๊ฐ๋น์ผ IO ๊ฒ์ ์ํ
});
const findStudent = safeFindObject(DB('student')).memoize();
findStudent('444-44-4444');
- ๋จํญ ํจ์๋ก ๋ง๋ค๋ฉด ๋ค๋ฃจ๊ธฐ ์ฝ๊ณ ํฉ์ฑํ๊ธฐ๋ ์ฌ์ธ ๋ฟ๋ง ์๋๋ผ, ํ๋ก๊ทธ๋จ์ ๋ ์๊ฒ ๋ถํดํ์ฌ ์ ์ฒด๋ฅผ ๊ตฌ์ฑํ๋ ์์๋ณ๋ก ๋ฉ๋ชจํํ๊ณ ์บ์๋ฅผ ์ ์ฉํ๋ ์ด์ ์ ์ด๋ฆด ์ ์๋ค.
๐ ๋ถํดํ์ฌ ๋ฉ๋ชจํ๋ฅผ ๊ทน๋ํโ
- ์ฝ๋๋ฅผ ์๊ฒ ๋๋์๋ก ๋ฉ๋ชจํ ํจ๊ณผ๋ ๋์ฑ ์ปค์ง๋ค.
- ๋ฉ๋ชจํ๊ฐ ์ผ์ข ์ ์์ ์ฟผ๋ฆฌ ์บ์ ์ญํ ์ ๋ด๋นํ๋ฉด์ ์ด๋ฏธ ์กฐํํ ๊ฐ์ฒด๋ฅผ ๋ค์์ ๋นจ๋ฆฌ ์ ๊ทผํ ์ ์๊ฒ ๋ณด๊ดํ๋ค๋ ์ ์ด๋ค.
- ํจ์๋ฅผ ์ด๋ค ๊ฐ, ์ฆ ๋๊ธํ๊ฒ ๊ณ์ฐ๋ ๊ฐ์ผ๋ก ๋ฐ๋ผ๋ณด๋ ๊ด์ ์์ ๋ฉ๋ชจํ๋ ํ์คํ ๊ทธ๋งํ ๊ฐ์น๊ฐ ์๋ค.
showStudent
์ ์๋ ์ผ๋ถ ํจ์๋ฅผ ๋ฉ๋ชจ๋ ํจ์๋ก ๋ณ๊ฒฝํ ์ฝ๋๋ค.
const showStudent = R.compose(
map(append('#student-info')),
liftIO,
getOrElse('ํ์์ ์ฐพ์ ์ ์์ต๋๋ค!'),
map(csv),
map(R.props(['ssn', 'firstname', 'lastname'])),
chain(findStudent),
chain(checkLengthSsn),
lift(cleanInput),
);
showStudent('444-44-4444').run(); // ํ๊ท 9.2 ๋ฐ๋ฆฌ์ด (๋ฉ๋ชจํ X)
showStudent('444-44-4444').run(); // ํ๊ท 2.5 ๋ฐ๋ฆฌ์ด (๋ฉ๋ชจํ O)