๋ณธ๋ฌธ์œผ๋กœ ๊ฑด๋„ˆ๋›ฐ๊ธฐ

๐ŸŒˆ Chapter 7 : ์œ ์—ฐํ•œ ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด๋ผ.

๐ŸŽฏ ํ…Œ์ŠคํŠธํ•˜๊ธฐ ์‰ฌ์šด ํ•จ์ˆ˜๋ฅผ ์ž‘์„ฑํ•˜๋ผ.โ€‹

  • ํ…Œ์ŠคํŠธ๋ฅผ ์ž‘์„ฑํ•˜๋ฉด ์ฝ”๋“œ๋ฅผ ์‰ฝ๊ฒŒ ๋ฆฌํŒฉํ† ๋งํ•  ์ˆ˜ ์žˆ๊ณ , ์˜ค๋ž˜๋œ ์ฝ”๋“œ๋ฅผ ํ›จ์”ฌ ์‰ฝ๊ฒŒ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ๋˜ํ•œ, ์ผ๋ฐ˜์ ์œผ๋กœ ๋” ๋ช…ํ™•ํ•˜๊ณ  ๋ฒ„๊ทธ๊ฐ€ ์ ์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.
  • ํ…Œ์ŠคํŠธ ๊ฐ€๋Šฅํ•œ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋ฉด ์ฝ”๋“œ๊ฐ€ ์ ์ฐจ ๊ฐœ์„ ๋˜๊ณ , ํ…Œ์ŠคํŠธ๋ฅผ ์ž‘์„ฑํ•˜๊ธฐ ์‰ฌ์›Œ์ง€๋ฉฐ, ์‚ฌ์šฉ์ž ๊ฒฝํ—˜๋„ ๊ฐœ์„ ๋  ๊ฒƒ์ด๋‹ค.
  • ๋Œ€ํ‘œ์ ์ธ ํ…Œ์ŠคํŠธ ํ”„๋ ˆ์ž„์›Œํฌ์ธ ์žฌ์Šค๋ฏผ(Jasmine), ๋ชจ์นด(Mocha), ์ œ์ŠคํŠธ(Jest) ๊ฐ€ ์žˆ๋‹ค. (๋ชจ์นด ์ถ”๊ฐ€ ์ฐธ๊ณ )
  • ์ด ์ฑ…์˜ ์˜ˆ์ œ ์ฝ”๋“œ๋ฅผ ์œ„ํ•ด ์ž‘์„ฑ๋œ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋Š” ํ…Œ์ŠคํŠธ ์‹คํ–‰๊ธฐ๋กœ ๋ชจ์นด๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋‹ค.
  • ์•„๋ž˜๋Š” ์กฐ๊ธˆ ๋ณต์žกํ•œ ์ฝ”๋“œ์ด๋‹ค.
import { getTaxInformation } from './taxService';

function formatPrice(user, { price, location }) {
const rate = getTaxInformation(location); // <label id="test.external" />
const taxes = rate ? `์ถ”๊ฐ€ ์„ธ๊ธˆ $${price * rate}` : '์ถ”๊ฐ€ ์„ธ๊ธˆ';

return `${user}๋‹˜์˜ ํ•จ๊ป˜ ๊ธˆ์•ก: $${price} ๋ฐ ${taxes}`;
}

export { formatPrice };
  • ํ…Œ์ŠคํŠธํ•  ๋•Œ ์–ด๋ ค์šด ๋ถ€๋ถ„์€ const rate = getTaxInformation(location);์ด ๋ถ€๋ถ„์œผ๋กœ ์™ธ๋ถ€ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ ์‹œ์ž‘๋œ๋‹ค.
  • ๋ถˆ๋Ÿฌ์˜จ ํ•จ์ˆ˜๋ฅผ ์ง์ ‘ ์‚ฌ์šฉํ•  ๋•Œ๋Š” ํ…Œ์ŠคํŠธํ•˜๋ ค๋Š” ํ•จ์ˆ˜๊ฐ€ ๋ถˆ๋Ÿฌ์˜จ ํ•จ์ˆ˜์™€ ๋ฐ€์ ‘ํ•˜๊ฒŒ ๊ฒฐํ•ฉ๋˜๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ๋‹ค.
  • ์ฆ‰, ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•  ๋•Œ ํ…Œ์ŠคํŠธ๊ฐ€ ์™ธ๋ถ€ API์—๋„ ์ ‘๊ทผํ•ด์•ผ ํ•˜๋ฉฐ, ๊ทธ ๊ฒฐ๊ณผ ํ…Œ์ŠคํŠธ๋Š” ๋„คํŠธ์›Œํฌ ์ ‘๊ทผ, ์‘๋‹ต ์‹œ๊ฐ„ ๋“ฑ์— ์˜์กดํ•˜๊ฒŒ ๋œ ๊ฒƒ์ด๋‹ค.
  • ์ด ๋ฌธ์ œ๋ฅผ ํ”ผํ•˜๋ ค๋ฉด ๋ชจ์˜ ๊ฐ์ฒด(mock)๋ฅผ ์ƒ์„ฑํ•ด์„œ ํ•จ์ˆ˜๋ฅผ ๊ฐ€๋กœ์ฑ„๊ณ  ๋ช…์‹œ์ ์ธ ๋ฐ˜ํ™˜๊ฐ’์„ ์„ค์ •ํ•˜๊ฒŒ ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค.
import expect from 'expect';

import sinon from 'sinon';
import * as taxService from './taxService';
import { formatPrice } from './problem';

describe('๊ฐ€๊ฒฉ ํ‘œ์‹œ', () => {
let taxStub;

beforeEach(() => {
// getTaxInformation ํ•จ์ˆ˜๋ฅผ ๋ฎ์–ด ์จ์„œ ๊ฐ„๋‹จํ•œ ๋ฐ˜ํ™˜๊ฐ’์ด ๋˜๋„๋ก ์Šคํ…(stub)์„ ์ƒ์„ฑํ•œ๋‹ค.
// ์Šคํ…์„ ๋งŒ๋“ค ๋•Œ ๋ถˆ๋Ÿฌ์˜จ ์ฝ”๋“œ๋Š” ๊ฑด๋„ˆ๋›ฐ๊ธฐ ๋•Œ๋ฌธ์— ์‹ค์ œ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜์ง€ ์•Š๊ณ  ์ถœ๋ ฅ๋  ๊ฐ’๋งŒ ์„ ์–ธํ•œ๋‹ค.
// ์Šคํ…์„ ์‚ฌ์šฉํ•  ๋•Œ ์žฅ์ ์€ ์–ด๋–ค ์ข…๋ฅ˜๋“  ์™ธ๋ถ€ ์˜์กด์„ฑ์„ ๊ฑฑ์ •ํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค.
taxStub = sinon.stub(taxService, 'getTaxInformation'); // <label id="test.stub" />
});

// ํ…Œ์ŠคํŠธ ๊พธ๋Ÿฌ๋ฏธ๊ฐ€ ์ข…๋ฃŒ๋˜๋ฉด ์›๋ž˜์˜ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋„๋ก ์ฝ”๋“œ๋ฅผ ๋ณต๊ตฌํ•ด์ค˜์•ผ ํ•œ๋‹ค.
// ์ฝ”๋“œ๋ฅผ ๋ณต๊ตฌํ•˜๋Š” ๊ฒƒ์€ ํ•„์ˆ˜ ๋‹จ๊ณ„์ด๋‹ค.
afterEach(() => {
taxStub.restore(); // <label id="test.restore" />
});

it('์„ธ๊ธˆ ์ •๋ณด๊ฐ€ ์—†์œผ๋ฉด ์„ธ๊ธˆ ์ถ”๊ฐ€๋ฅผ ์•ˆ๋‚ดํ•ด์•ผ ํ•œ๋‹ค', () => {
// ์Šคํ…์„ ์‚ฌ์šฉํ•œ ์˜ˆ
taxStub.returns(null); // <label id="test.stub2" />
const item = { price: 30, location: 'Oklahoma' };
const user = 'Aaron Cometbus';
const message = formatPrice(user, item);
const expectedMessage = 'Aaron Cometbus๋‹˜์˜ ํ•ฉ๊ณ„ ๊ธˆ์•ก: $30 ๋ฐ ์ถ”๊ฐ€ ์„ธ๊ธˆ';
expect(message).toEqual(expectedMessage);
});

it('์„ธ๊ธˆ ์ •๋ณด๊ฐ€ ์žˆ์œผ๋ฉด ์„ธ๊ธˆ ๊ธˆ์•ก์„ ์•Œ๋ ค์ค˜์•ผ ํ•œ๋‹ค', () => {
taxStub.returns(0.1);

const item = { price: 30, location: 'Oklahoma' };
const user = 'Aaron Cometbus';
const message = formatPrice(user, item);
const expectedMessage = 'Aaron Cometbus๋‹˜์˜ ํ•ฉ๊ณ„ ๊ธˆ์•ก: $30 ๋ฐ ์ถ”๊ฐ€ ์„ธ๊ธˆ $3';
expect(message).toEqual(expectedMessage);
});
});
  • ํ…Œ์ŠคํŠธ ์ฝ”๋“œ์— ์ŠคํŒŒ์ด(spy), ๋ชจ์˜ ๊ฐ์ฒด, ์Šคํ…๊ณผ ๊ฐ™์€ ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ์™ธ๋ถ€ ํ—ฌํผ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋‹ค๋ฉด, ์ฝ”๋“œ๊ฐ€ ๋ณต์žกํ•˜๊ณ  ๊ฐ•ํ•˜๊ฒŒ ๊ฒฐํ•ฉํ•ด ์žˆ๋‹ค๋Š” ์ฆ๊ฑฐ๋กœ ์ฝ”๋“œ๋ฅผ ๋‹จ์ˆœํ™”ํ•ด์•ผ ํ•œ๋‹ค.
  • ์ด๋Ÿด ๊ฒฝ์šฐ ์™ธ๋ถ€ ํ•จ์ˆ˜๋ฅผ ์ธ์ˆ˜๋กœ ์ „๋‹ฌํ•˜๋„๋ก ๋ฐ”๊พธ๊ธฐ๋งŒ ํ•˜๋ฉด ๋œ๋‹ค.
  • ์˜์กด์„ฑ์„ ์ธ์ˆ˜๋กœ ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ์„ ์˜์กด์„ฑ ์ฃผ์ž…(dependency injection)์ด๋ผ๊ณ  ํ•œ๋‹ค.
  • ์ฝ”๋“œ์˜ ๊ฒฐํ•ฉ์„ ์ œ๊ฑฐํ•˜๋ ค๋ฉด getTaxInformation()์„ ์ธ์ˆ˜๋กœ ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ๋งŒ์œผ๋กœ ์ถฉ๋ถ„ํ•˜๋‹ค.
function formatPrice(user, { price, location }, getTaxInformation) {
const rate = getTaxInformation(location);
const taxes = rate ? `์ถ”๊ฐ€ ์„ธ๊ธˆ $${price * rate}` : '์ถ”๊ฐ€ ์„ธ๊ธˆ';

return `${user}๋‹˜์˜ ํ•จ๊ป˜ ๊ธˆ์•ก: $${price} ๋ฐ ${taxes}`;
}

export { formatPrice };
  • ์œ„์™€ ๊ฐ™์ด ํ•˜๋ฉด ์˜์กด์„ฑ ์ฃผ์ž…์„ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์Šคํ…์ด ํ•„์š”ํ•˜์ง€ ์•Š๊ฒŒ ๋œ๋‹ค.
  • ํŠน์ •ํ•œ ์ž…๋ ฅ๊ฐ’์„ ๋ฐ›์€ formatPrice()๊ฐ€ ํŠน์ •ํ•œ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š”์ง€ ํ…Œ์ŠคํŠธํ•œ๋‹ค.
import expect from 'expect';

import { formatPrice } from './test';

describe('๊ฐ€๊ฒฉ ํ‘œ์‹œ', () => {
it('์„ธ๊ธˆ ์ •๋ณด๊ฐ€ ์—†์œผ๋ฉด ์„ธ๊ธˆ ์ถ”๊ฐ€๋ฅผ ์•ˆ๋‚ดํ•ด์•ผ ํ•œ๋‹ค', () => {
const item = { price: 30, location: 'Oklahoma' };
const user = 'Aaron Cometbus';
const message = formatPrice(user, item, () => null);
expect(message).toEqual('Aaron Cometbus๋‹˜์˜ ํ•ฉ๊ณ„ ๊ธˆ์•ก: $30 ๋ฐ ์ถ”๊ฐ€ ์„ธ๊ธˆ');
});

it('์„ธ๊ธˆ ์ •๋ณด๊ฐ€ ์žˆ์œผ๋ฉด ์„ธ๊ธˆ ๊ธˆ์•ก์„ ์•Œ๋ ค์ค˜์•ผ ํ•œ๋‹ค', () => {
const item = { price: 30, location: 'Oklahoma' };
const user = 'Aaron Cometbus';
const message = formatPrice(user, item, () => 0.1);
expect(message).toEqual('Aaron Cometbus๋‹˜์˜ ํ•ฉ๊ณ„ ๊ธˆ์•ก: $30 ๋ฐ ์ถ”๊ฐ€ ์„ธ๊ธˆ $3');
});
});
  • ํ…Œ์ŠคํŠธ ๋Œ€์ƒ์ธ ํ•จ์ˆ˜์™€ expect๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์™ธ์—๋Š” ์•„๋ฌด๊ฒƒ๋„ ํ•„์š”ํ•˜์ง€ ์•Š๋‹ค. ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๊ธฐ๊ฐ€ ๋” ์‰ฌ์›Œ์กŒ๊ณ , ์ฝ”๋“œ๊ฐ€ ๋‹จ์ผ ์ฑ…์ž„์„ ๊ฐ–๋„๋ก ์ฑ…์ž„์„ ์ค„์ด๋Š” ๋ฉด์—์„œ๋„ ๋”์šฑ ํšจ๊ณผ์ ์ด๋‹ค.
  • ์ฝ”๋“œ์—๋Š” ๋ช‡ ๊ฐ€์ง€ ๋ถ€์ˆ˜ ํšจ๊ณผ์™€ ์ž…์ถœ๋ ฅ์ด ์žˆ์„ ์ˆ˜ ์žˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋ถ€๋ถ„์€ ์ตœ๋Œ€ํ•œ ์ ๊ฒŒ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ํ…Œ์ŠคํŠธ ๊ฐ€๋Šฅํ•œ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๋ฌ˜์ˆ˜์ด๋‹ค.
  • ๋งŒ์•ฝ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๊ธฐ ์–ด๋ ต๋‹ค๋ฉด ์ฝ”๋“œ๋ฅผ ๋ณ€๊ฒฝํ•ด์•ผ ํ•œ๋‹ค.
  • ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํ…Œ์ŠคํŠธ์—์„œ ๋ฐœ์ƒํ•˜๋Š” ๋‹ค๋ฅธ ๋ฌธ์ œ

๐ŸŽฏ ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋กœ ๋ณต์žก๋„๋ฅผ ๋‚ฎ์ถฐ๋ผ.โ€‹

  • ์•„๋ž˜์˜ ์ฝ”๋“œ๋ฅผ ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋กœ ๋ณ€๊ฒฝํ•ด ๋ณด์ž.
const myinfo = {
first: 'seungmin',
last: 'sa',
city: 'Daejoen',
state: 'still studying'
};
// ํ•ด์ฒด ํ• ๋‹น ์‚ฌ์šฉ
function getName({ first, last }) {
return `${first} ${last}`;
}
  • ๋งค๊ฐœ๋ณ€์ˆ˜์—์„œ ํ•ด์ฒด ํ• ๋‹น, ๋‚˜๋จธ์ง€ ๋งค๊ฐœ๋ณ€์ˆ˜, ๋งค๊ฐœ๋ณ€์ˆ˜ ๊ธฐ๋ณธ๊ฐ’ ๋“ฑ์„ ์‚ฌ์šฉํ•˜๋Š” ํŠน๋ณ„ํ•œ ๋งค๊ฐœ๋ณ€์ˆ˜์˜ ๊ฒฝ์šฐ์—๋Š” ๊ด„ํ˜ธ๋ฅผ ํฌํ•จํ•ด์•ผ ํ•œ๋‹ค.
  • ๊ด„ํ˜ธ๊ฐ€ ์—†์œผ๋ฉด ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์—”์ง„์€ ์šฐ๋ฆฌ๊ฐ€ ๊ฐ์ฒด ์„ ์–ธ์ด ์•„๋‹ˆ๋ผ ํ•จ์ˆ˜ ์„ ์–ธ์„ ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์ž˜ ์•Œ์ง€ ๋ชปํ•œ๋‹ค.
const getName = { first, last } => `${first} ${last}`;
// Uncaught SyntaxError: Malformed arrow function parameter list
// ์ž˜๋ชป๋œ ํ™”์‚ดํ‘œ ํ•จ์ˆ˜ ๋งค๊ฐœ๋ณ€์ˆ˜ ๋ชฉ๋ก
const getName = ({ first, last }) => `${first} ${last}`;
getName(myinfo);
// "seungmin sa"
  • ํ™”์‚ดํ‘œ ํ•จ์ˆ˜์—์„œ ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒฝ์šฐ์— return๋ฌธ์„ ์ƒ๋žตํ•œ๋‹ค๋ฉด ํ™”์‚ดํ‘œ ํ•จ์ˆ˜์—์„œ ํ™”์‚ดํ‘œ ์šฐ์ธก์— ์žˆ๋Š” ์ค‘๊ด„ํ˜ธ๋Š” ๊ฐ์ฒด๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๊ฒƒ์ธ์ง€, ์•„๋‹ˆ๋ฉด ํ•จ์ˆ˜ ๋ชธ์ฒด๋ฅผ ๊ฐ์‹ธ๋Š” ๊ฒƒ์ธ์ง€ ๊ตฌ๋ถ„ํ•˜๊ธฐ ์–ด๋ ต๋‹ค.
  • ๋”ฐ๋ผ์„œ ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒฝ์šฐ์—๋Š” ๊ฐ์ฒด๋ฅผ ๊ด„ํ˜ธ๋กœ ๊ฐ์‹ธ์•ผ ํ•œ๋‹ค.
const getName = ({ first, last }) => ({ fullName: `${first} ${last}` });
getName(myinfo);
// {fullName: ""seungmin sa""}
  • ๊ด„ํ˜ธ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•  ๋•Œ๋Š” ์ฝ”๋“œ๋ฅผ ์—ฌ๋Ÿฌ ์ค„์— ๊ฑธ์ณ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.
  • return ๋ฌธ์„ ์ƒ๋žตํ•˜๋Š” ๋™์‹œ์— ๋ฐ˜ํ™˜๊ฐ’์„ ์—ฌ๋Ÿฌ ์ค„๋กœ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.
const getNameAndLocation = ({ first, last, city, state }) => ({
fullName: `${first} ${last}`,
location: `${city} ${state}`,
});
getNameAndLocation(myinfo);
// {fullName: "seungmin sa", location: "Daejoen still studying"}
const discounter = discount => {
return price => {
return price * (1 - discount);
};
};
const tenPercentOff = discounter(0.1);
tenPercentOff(100);
// 90
  • return ์—†์ด ์ค‘๊ด„ํ˜ธ ์—†์ด ํ•จ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ๋‹ค.
const discounter = discount => price => price * (1 - discount);

const tenPercentOff = discounter(0.1);
tenPercentOff(100);
// 90
  • ๊ณ ์ฐจ ํ•จ์ˆ˜๋Š” ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๊ฐ€๋‘๋Š” ๋ฐ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์„ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ, ๋ฐฐ์—ด ๋ฉ”์„œ๋“œ์™€ ๋‚˜๋จธ์ง€ ๋งค๊ฐœ๋ณ€์ˆ˜์—๋„ ๋„์›€์„ ์ค„ ์ˆ˜ ์žˆ๋‹ค.
  • ์•„๋ž˜ ๋ฐฉ๋ฒ•์€ ๊ณ ์ฐจ ํ•จ์ˆ˜๋ฅผ ๋‘ ๊ฐœ์˜ ๋‹ค๋ฅธ ๋งค๊ฐœ๋ณ€์ˆ˜ ์ง‘ํ•ฉ์„ ๊ฐ€์ง„ ๋‹จ์ผ ํ•จ์ˆ˜๋กœ ๋ณ€ํ™˜ํ•  ๋•Œ ํ•„์ˆ˜์ ์œผ๋กœ ์‚ฌ์šฉํ•œ๋‹ค.
discounter(0,1)(100);
// 90

๐ŸŽฏ ๋ถ€๋ถ„ ์ ์šฉ ํ•จ์ˆ˜๋กœ ๋‹จ์ผ ์ฑ…์ž„ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๊ด€๋ฆฌํ•˜๋ผ.โ€‹

  • ๊ณ ์ฐจ ํ•จ์ˆ˜๋Š” ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๊ฐ€๋‘๋Š” ๋ฐฉ๋ฒ•์„ ํ†ตํ•ด ํŠน๋ณ„ํ•œ ๊ฐ’์„ ์ œ๊ณตํ•˜๋ฏ€๋กœ, ๋‚˜์ค‘์— ์›๋ž˜์˜ ์ธ์ˆ˜์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด๋‘๊ณ  ํ•จ์ˆ˜ ์‹คํ–‰์„ ๋งˆ์น  ์ˆ˜ ์žˆ๋‹ค.
  • ๋˜ํ•œ, ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๋ถ„๋ฆฌํ•ด ํ•จ์ˆ˜์˜ ์˜๋„๋ฅผ ๋ช…ํ™•ํ•˜๊ฒŒ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • **๋ถ€๋ถ„ ์ ์šฉ ํ•จ์ˆ˜(partially applied function)**๋ฅผ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ, ์ผ๋ถ€ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ „๋‹ฌํ•˜๋ฉด ํ•ด๋‹น ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ž ๊ทธ๋Š” ํ•จ์ˆ˜๊ฐ€ ๋ฐ˜ํ™˜๋˜์–ด ์—ฌ๊ธฐ์— ๋” ๋งŽ์€ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ์ฆ‰, ๋ถ€๋ถ„ ์ ์šฉ ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•˜๋ฉด ํ•œ ๋ฒˆ์— ์ „๋‹ฌํ•ด์•ผ ํ•  ํ•จ์ˆ˜ ์ธ์ˆ˜์˜ ์ˆ˜๊ฐ€ ์ค„์–ด๋“œ๋Š” ๋Œ€์‹  ์ธ์ˆ˜๋ฅผ ๋” ์ „๋‹ฌํ•ด์•ผ ํ•˜๋Š” ๋‹ค๋ฅธ ํ•จ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
  • ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ์„œ๋กœ ๋…๋ฆฝ์ ์ธ ์—ฌ๋Ÿฌ ๋งค๊ฐœ๋ณ€์ˆ˜ ์ง‘ํ•ฉ์„ ๋‘˜ ์ˆ˜ ์žˆ๋‹ค. (๋‹จ์ผ ์ฑ…์ž„์„ ์ง€๊ฒŒ ๋œ๋‹ค.)
  • ๋‹ค์Œ์€ ์˜ˆ์ œ ๊ฐ์ฒด ์ •๋ณด์ด๋‹ค.
const building = {
hours: '8 a.m. - 8 p.m.',
address: 'Jayhawk Blvd',
};
const manager = {
name: 'Augusto',
phone: '555-555-5555',
};
const program = {
name: 'Presenting Research',
room: '415',
hours: '3 - 6',
};
const exhibit = {
name: 'Emerging Scholarship',
contact: 'Dyan',
};
  • ์•„๋ž˜๋Š” building, manager, program๋˜๋Š” exhibit์˜ ์„ธ ๊ฐ€์ง€ ์ธ์ˆ˜๋ฅผ ๋ฐ›์•„ ํ•˜๋‚˜์˜ ์ •๋ณด ์ง‘ํ•ฉ์œผ๋กœ ๊ฒฐํ•ฉํ•˜๋Š” ํ•จ์ˆ˜์ด๋‹ค.
function mergeProgramInfomation(building, manager, event) {
const { hours, address } = building;
const { name, phone } = manager;
const defaults = {
hours,
address,
contact: name,
phone,
};

return { ...defaults, ...event };
}
  • ์ฝ”๋“œ๋ฅผ ์‚ดํŽด๋ณด๋ฉด, ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ๋งˆ๋‹ค ์ „๋‹ฌํ•˜๋Š” ์ฒซ ๋ฒˆ์งธ ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” building์œผ๋กœ ํ•ญ์ƒ ๋™์ผํ•˜๋‹ค. ์ด ํ•จ์ˆ˜๋ฅผ ๋ฐ˜๋ณตํ•ด์„œ ํ˜ธ์ถœํ•˜๊ณ  ์žˆ๋‹ค.
  • ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ์ด๋Ÿฐ ๋ฐ˜๋ณต์€ ํ•จ์ˆ˜๊ฐ€ ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ๋ถ„๋ฆฌ๋  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.
const programInfo = mergeProgramInfomation(building, manager, program);
const exhibitInfo = mergeProgramInfomation(building, manager, exhibit);
  • ์œ„ ์ฝ”๋“œ๋ฅผ ๊ณ ์ฐจ ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•ด์„œ ๋‹จ์ผ ์ฑ…์ž„ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๋งŒ๋“ค๋ฉด ์•ž์— ์œ„์น˜ํ•œ ๋‘ ๊ฐœ์˜ ์ธ์ˆ˜๋ฅผ ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ์™ธ๋ถ€ ํ•จ์ˆ˜๋Š” ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ building๊ณผ manager๋งŒ ๊ฐ–๊ณ , ์ด ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ program ํ•˜๋‚˜๋งŒ ์‚ฌ์šฉํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋„๋ก ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค.
function mergeProgramInfomation(building, manager) {
const { hours, address } = building;
const { name, phone } = manager;
const defaults = {
hours,
address,
contact: name,
phone,
};

return program => {
return { ...defaults, ...program };
}
}
  • ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋‹ค.
const programInfo = mergeProgramInfomation(building, manager)(program);
// {
// address: "Jayhawk Blvd",
// contact: "Augusto",
// hours: "3 - 6",
// name: "Presenting Research",
// phone: "555-555-5555",
// room: "415",
// }
const exhibitInfo = mergeProgramInfomation(building, manager)(exhibit);
// {
// address: "Jayhawk Blvd",
// contact: "Dyan",
// hours: "8 a.m. - 8 p.m.",
// name: "Emerging Scholarship",
// phone: "555-555-5555",
// }
  • ๋งค๊ฐœ๋ณ€์ˆ˜์— ๋‹จ์ผ ์ฑ…์ž„์„ ๋ถ€์—ฌํ•˜๊ธฐ๋Š” ํ–ˆ์ง€๋งŒ ๋ฐ˜๋ณต๊นŒ์ง€ ์ œ๊ฑฐ๋˜์ง€๋Š” ๋ชปํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ถ€๋ถ„ ์ ์šฉ์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค. (๋‹ค์Œ ํŒ์—์„œ)
  • ๋ถ€๋ถ„ ์ ์šฉ๊ณผ ๊ณ ์ฐจ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด ๋งค๊ฐœ๋ณ€์ˆ˜์— ๋‹จ์ผ ์ฑ…์ž„์„ ๋ถ€์—ฌํ•˜๋Š” ๋ฐ๋Š” ๋‚˜๋จธ์ง€ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
  • ๋ฐฐ์—ด์— ๋ฐ์ดํ„ฐ๊ฐ€ ์žˆ๊ฑฐ๋‚˜ ์›๋ณธ ๋ฐ์ดํ„ฐ์— ์ผ๋Œ€์ผ๋กœ ๋Œ€์‘๋˜๋Š” ์ถ”๊ฐ€ ๋ฐ์ดํ„ฐ๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ ์‚ฌ์šฉํ•˜๋ฉด ์ข‹๋‹ค.
const birds = ['meadowlark', 'robin', 'roadrunner'];
const zip = (...left) => (...right) => {
return left.map((item, i) => [item, right[i]]);
};
zip('kansas', 'wisconsin', 'new mexico')(...birds);
// [
// ["kansas", "meadowlark"],
// ["wisconsin", "robin"],
// ["new mexico", "roadrunner"]
// ]

๐ŸŽฏ ์ปค๋ง๊ณผ ๋ฐฐ์—ด ๋ฉ”์„œ๋“œ๋ฅผ ์กฐํ•ฉํ•œ ๋ถ€๋ถ„ ์ ์šฉ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋ผ.โ€‹

  • ์ด์ „ ๊ณ ์ฐจ ํ•จ์ˆ˜์™€ ๋ถ€๋ถ„ ์ ์šฉ์„ ์ด์šฉํ•ด ๋งค๊ฐœ๋ณ€์ˆ˜์— ๋‹จ์ผ ์ฑ…์ž„์„ ๋ถ€์—ฌํ•˜๋Š” ๋ฐฉ๋ฒ•์œผ๋กœ ๊ด€๋ จ์ด ์—†๋Š” ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์ธํ•œ ๋ฌธ์ œ๋Š” ํ•ด๊ฒฐํ–ˆ์ง€๋งŒ, ๊ฐ™์€ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๋ฐ˜๋ณตํ•ด์„œ ์‚ฌ์šฉํ•˜๋Š” ๋ฌธ์ œ๋Š” ํ•ด๊ฒฐํ•  ์ˆ˜ ์—†์—ˆ๋‹ค.
  • ๊ณ ์ฐจ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ฐ’์„ ํ•œ ๋ฒˆ ์ €์žฅํ•œ ํ›„ ๋‚˜์ค‘์— ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์ƒˆ๋กœ์šด ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด์„œ ๋ฐ˜๋ณต์„ ํ”ผํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ๊ณ ์ฐจ ํ•จ์ˆ˜์—์„œ ๋ฐ˜ํ™˜๋œ ํ•จ์ˆ˜๋Š” ๋ฐ”๋กœ ๋‹ค์‹œ ํ˜ธ์ถœํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค. ๊ณ ์ฐจ ํ•จ์ˆ˜๋ฅผ ํ•œ ๋ฒˆ ํ˜ธ์ถœํ•˜๋ฉด ๊ณ„์†ํ•ด์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์ƒˆ๋กœ์šด ํ•จ์ˆ˜๊ฐ€ ๋ฐ˜ํ™˜๋˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
  • ๋งˆ์น˜ ์ธ์ˆ˜๋ฅผ ํ•˜๋“œ ์ฝ”๋”ฉํ•ด๋‘” ํ•จ์ˆ˜๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™๋‹ค.
  • ์ด์ „์— ์‚ฌ์šฉํ–ˆ๋˜ ์˜ˆ์ œ ์ฝ”๋“œ๋ฅผ ์žฌ์‚ฌ์šฉํ•œ๋‹ค.
const setStrongHallProgram = mergeProgramInfomation(building, manager);
const programInfo = setStrongHallProgram(program);
const exhibitInfo = setStrongHallProgram(exhibit);
  • ๊ณ ์ฐจ ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•˜๋ฉด ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๋ณ„๋„๋กœ ๋ถ„๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋ ‡์ง€๋งŒ ํ•จ์ˆ˜๋ฅผ ์™„์ „ํžˆ ๋ถ„๋ฆฌํ•˜๊ธฐ ์ „์— ํ•จ์ˆ˜์— ํ•„์š”ํ•œ ์ธ์ˆ˜์˜ ์ˆ˜๋ฅผ ์ค„์ผ ์ˆ˜ ์žˆ๋„๋ก ์ธ์ˆ˜๋ฅผ ๋ถ„๋ฆฌํ•˜๋Š” ๊ฒƒ์ด ํ›จ์”ฌ ๋” ์ข‹๋‹ค.
  • ํ•œ ๋ฒˆ์— ์ธ์ˆ˜๋ฅผ ํ•˜๋‚˜๋งŒ ๋ฐ›๋Š” ํ•จ์ˆ˜๋ฅผ ์ปค๋ง(currying) ์ด๋ผ๊ณ  ํ•˜๋ฉฐ, ์ด๋Š” ํ•˜๋‚˜์˜ ์ธ์ˆ˜๋งŒ ์ „๋‹ฌํ•˜๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ๋‹ค๋ฃฐ ๋•Œ ๋งค์šฐ ์œ ์šฉํ•˜๋‹ค.
  • ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ์ˆœ์ˆ˜ํ•œ ํ˜•ํƒœ์˜ ์ปค๋ง์„ ์™„๋ฒฝํ•˜๊ฒŒ ์ง€์›ํ•˜์ง€๋Š” ์•Š์ง€๋งŒ, ๋ถ€๋ถ„ ์ ์šฉ์„ ์ด์šฉํ•ด์„œ ์ผ๋ จ์˜ ๋‹จ์ผ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋งค๊ฐœ๋ณ€์ˆ˜ ์ˆซ์ž๋ฅผ ์ค„์ด๋Š” ๋ฐฉ๋ฒ•์ด ์ผ๋ฐ˜์ ์ด๋‹ค.

๐Ÿ“Œ ์ปค๋ง๊ณผ ๋ถ€๋ถ„ ์ ์šฉโ€‹

  • ๋ถ€๋ถ„ ์ ์šฉ(partial application) ํ•จ์ˆ˜๋Š” ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์—ฌ๋Ÿฌ ๋ฒˆ ๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค.
  • ๋ถ€๋ถ„ ์ ์šฉ ํ•จ์ˆ˜์™€ ์ปค๋ง ํ•จ์ˆ˜๋Š” ๋ชจ๋‘ ์›๋ž˜๋ณด๋‹ค ํ•„์š”ํ•œ ์ธ์ˆ˜์˜ ์ˆ˜๊ฐ€ ์ ์€ ํ•จ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•ด ์ธ์ˆ˜ ์ˆ˜๋ฅผ ์ค„์ผ ์ˆ˜ ์žˆ๋‹ค.
  • ํ•จ์ˆ˜์—๋Š” ํ•จ์ˆ˜๊ฐ€ ๋ฐ›์„ ์ˆ˜ ์žˆ๋Š” ์ „์ฒด ์ธ์ˆ˜์˜ ์ˆ˜๊ฐ€ ์žˆ์œผ๋ฉฐ ํ•ญ์ˆ˜๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค.
  • ๋ถ€๋ถ„ ์ ์šฉ ํ•จ์ˆ˜๋Š” ์›๋ž˜์˜ ํ•จ์ˆ˜๋ณด๋‹ค ํ•ญ์ˆ˜๊ฐ€ ์ ์€ ํ•จ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค. ์ธ์ˆ˜๊ฐ€ ์ด ์„ธ ๊ฐœ ํ•„์š”ํ•œ ๊ฒฝ์šฐ์— ํ•จ์ˆ˜๋Š” ์„ธ ๊ฐœ์˜ ์ธ์ˆ˜๊ฐ€ ํ•„์š”ํ–ˆ์ง€๋งŒ, ์—ฌ๊ธฐ์— ๋ถ€๋ถ„ ์ ์šฉ ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•˜๋ฉด ํ•ญ์ˆ˜๊ฐ€ ํ•˜๋‚˜์ธ ํ•จ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
  • ๋ฐ˜๋ฉด ์ปค๋ง ํ•จ์ˆ˜๋Š” ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์ธ์ˆ˜๋ฅผ ๋ฐ›๋Š” ํ•จ์ˆ˜์—์„œ ์ •ํ™•ํžˆ ์ธ์ˆ˜ ํ•˜๋‚˜๋งŒ ๋ฐ›๋Š” ์ผ๋ จ์˜ ํ•จ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•  ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค. ๊ฐ€๋ น ์ธ์ˆ˜ ์„ธ ๊ฐœ๊ฐ€ ํ•„์š”ํ•œ ํ•จ์ˆ˜๊ฐ€ ์žˆ๋‹ค๋ฉด, ๋จผ์ € ์ธ์ˆ˜ ํ•˜๋‚˜๋ฅผ ๋ฐ›๋Š” ๊ณ ์ฐจ ํ•จ์ˆ˜๊ฐ€ ๋‹ค๋ฅธ ํ•จ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ณ , ๋ฐ˜ํ™˜๋œ ํ•จ์ˆ˜๋„ ์ธ์ˆ˜ ํ•˜๋‚˜๋ฅผ ๋ฐ›๋Š”๋‹ค. ์ด ํ•จ์ˆ˜์—์„œ ๋์œผ๋กœ ์ธ์ˆ˜ ํ•˜๋‚˜๋ฅผ ๋ฐ›๋Š” ๋งˆ์ง€๋ง‰ ํ•จ์ˆ˜๊ฐ€ ๋ฐ˜ํ™˜๋œ๋‹ค.
  • ๋‹ค์Œ ๊ฐ์ฒด ๋ฐฐ์—ด ์˜ˆ์ œ๋ฅผ ์‚ฌ์šฉํ•ด ๋ณด์ž.
const dogs = [
{
์ด๋ฆ„: '๋งฅ์Šค',
๋ฌด๊ฒŒ: 10,
๊ฒฌ์ข…: '๋ณด์Šคํ„ดํ…Œ๋ฆฌ์–ด',
์ง€์—ญ: '์œ„์Šค์ฝ˜์‹ ',
์ƒ‰์ƒ: '๊ฒ€์ •์ƒ‰',
},
{
์ด๋ฆ„: '๋„๋‹ˆ',
๋ฌด๊ฒŒ: 90,
๊ฒฌ์ข…: '๋ ˆ๋ธŒ๋ผ๋„๋ ˆํŠธ๋ฆฌ๋ฒ„',
์ง€์—ญ: '์บ”์ž์Šค',
์ƒ‰์ƒ: '๊ฒ€์ •์ƒ‰',
},
{
์ด๋ฆ„: '์„€๋„',
๋ฌด๊ฒŒ: 40,
๊ฒฌ์ข…: '๋ž˜ํŠธ๋ผ๋„๋ ˆํŠธ๋ฆฌ๋ฒ„',
์ง€์—ญ: '์œ„์Šค์ฝ˜์‹ ',
์ƒ‰์ƒ: '๊ฐˆ์ƒ‰',
},
]
  • ์•„๋ž˜ ์ฝ”๋“œ๋Š” ๊ฐ•์•„์ง€ ๋ฐฐ์—ด๊ณผ ํ•„ํ„ฐ ์กฐ๊ฑด์„ ์ธ์ˆ˜๋กœ ๋ฐ›์€ ํ›„ ํ•„ํ„ฐ๋ง ์กฐ๊ฑด์— ๋งž๋Š” ๊ฐ•์•„์ง€์˜ ์ด๋ฆ„๋งŒ ๋ชจ์•„์„œ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜์ด๋‹ค.
function getDogNames(dogs, filter) {
const [key, value] = filter;
return dogs
.filter(dog => dog[key] === value)
.map(dog => dog['์ด๋ฆ„']);
}

getDogNames(dogs, ['์ƒ‰์ƒ', '๊ฒ€์ •์ƒ‰']); // ["๋งฅ์Šค", "๋„๋‹ˆ"]
  • ์œ„ ์ฝ”๋“œ๋Š” ๋‘ ๊ฐ€์ง€ ๋ฌธ์ œ๊ฐ€ ์žˆ๋‹ค.
  • ์ฒซ์งธ, ํ•„ํ„ฐ ํ•จ์ˆ˜์— ์ œ์•ฝ์ด ์žˆ๋‹ค. ํ•„ํ„ฐ ํ•จ์ˆ˜๋Š” ํ•„ํ„ฐ์™€ ๊ฐ๊ฐ์˜ ๊ฐ•์•„์ง€๋ฅผ ์ •ํ™•ํ•˜๊ฒŒ ๋น„๊ตํ•  ๋•Œ๋งŒ ์ •์ƒ์ ์œผ๋กœ ์ž‘๋™ํ•œ๋‹ค.
  • ๋‘˜์งธ, ๋ชจ๋“  ๋ฐฐ์—ด ๋ฉ”์„œ๋“œ์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ map()์€ ๊ฒ€์‚ฌํ•˜๋Š” ํ•ญ๋ชฉ๋งŒ ์ธ์ˆ˜๋กœ ๋ฐ›์„ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์œ ํšจ ๋ฒ”์œ„ ๋‚ด์˜ ๋‹ค๋ฅธ ๋ณ€์ˆ˜๋“ค์„ ๊ฐ€์ ธ์˜ฌ ๋ฐฉ๋ฒ•์ด ํ•„์š”ํ•˜๋‹ค. map()์€ ๋‹ค๋ฅธ ํ•จ์ˆ˜ ๋‚ด๋ถ€์˜ ํ•จ์ˆ˜์ด๋ฏ€๋กœ ์ด๋ฅผ ๊ฐ์‹ธ๊ณ  ์žˆ๋Š” ํ•จ์ˆ˜์˜ ๋ณ€์ˆ˜์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค. ์ฆ‰, ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ด์šฉํ•ด์„œ ์™ธ๋ถ€ ํ•จ์ˆ˜์— ํ•„์š”ํ•œ ๋ณ€์ˆ˜๋ฅผ ์ „๋‹ฌํ•  ๋ฐฉ๋ฒ•์ด ํ•„์š”ํ•˜๋‹ค.
  • ์ฒซ ๋ฒˆ์งธ ๋ฌธ์ œ๋Š” ๋น„๊ต ํ•จ์ˆ˜๋ฅผ ํ•˜๋“œ ์ฝ”๋”ฉํ•˜์ง€ ์•Š๊ณ  ํ•„ํ„ฐ ํ•จ์ˆ˜์— ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋กœ ์ „๋‹ฌํ•˜์—ฌ ํ•ด๊ฒฐ ํ•  ์ˆ˜ ์žˆ๋‹ค.
function getDogNames(dogs, filterFunc) {
return dogs
.filter(filterFunc)
.map(dog => dog['์ด๋ฆ„'])
}

getDogNames(dogs, dog => dog['๋ฌด๊ฒŒ'] < 20);
// ["๋งฅ์Šค"]
  • ํ•˜์ง€๋งŒ ์ˆซ์ž 20๊ณผ ๊ฐ™์€ ๊ฐ’์„ ํ•˜๋“œ ์ฝ”๋”ฉํ•˜๊ณ  ์žˆ๋‹ค. ์ฆ‰, ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ์ง์ ‘ ์ฝ”๋”ฉํ•ด์„œ ๋„ฃ๊ฑฐ๋‚˜ ์œ ํšจ ๋ฒ”์œ„์˜ ์ถฉ๋Œ์ด ์—†๋Š”์ง€ ํ™•์ธํ•˜๋Š” ์ ˆ์ฐจ๋ฅผ ๊ฑฐ์น˜๊ณ  ์žˆ๋‹ค.
  • ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ๋ถ€๋ถ„ ์ ์šฉ ํ•จ์ˆ˜๋ฅผ ๋ณ€์ˆ˜์— ํ• ๋‹นํ•ด์„œ ๋‹ค๋ฅธ ํ•จ์ˆ˜์— ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌํ•˜๋Š” ๋ฐฉ๋ฒ•์œผ๋กœ ๋‚˜๋จธ์ง€ ์ธ์ˆ˜๋ฅผ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์„œ๋กœ ๋‹ค๋ฅธ ๋ฌด๊ฒŒ๋ฅผ ๊ธฐ์ค€์œผ๋กœ ํ•ด๋„ ๊ณ„์†ํ•ด์„œ ํ•จ์ˆ˜๋ฅผ ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ์œ ํšจ ๋ฒ”์œ„ ์ถฉ๋Œ์ด ๋ฐœ์ƒํ•  ๊ฐ€๋Šฅ์„ฑ๋„ ๊ฑฐ์˜ ์—†๋‹ค.
const weightCheck = weight => dog => dog['๋ฌด๊ฒŒ'] < weight;

getDogNames(dogs, weightCheck(20));
// ["๋งฅ์Šค"]
getDogNames(dogs, weightCheck(50));
// ["๋งฅ์Šค", "์„€๋„"]
  • ์ปค๋ง ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์—ฌ๋Ÿฌ ์ง€์ ์—์„œ ๋‹ค์–‘ํ•œ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋‹ค. ๋˜ํ•œ, ํ•จ์ˆ˜๋ฅผ ๋ฐ์ดํ„ฐ๋กœ ์ „๋‹ฌํ•  ์ˆ˜๋„ ์žˆ๋‹ค.
  • ์ค‘์š”ํ•œ ๋ถ€๋ถ„์€ ๋ฐ˜๋“œ์‹œ ๋‘ ๊ฐœ์˜ ํ•จ์ˆ˜์™€ ๋‘ ๊ฐœ์˜ ์ธ์ˆ˜ ์ง‘ํ•ฉ์œผ๋กœ ์ œํ•œํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค๋Š” ์ ์œผ๋กœ ์ปค๋ง์„ ์‚ฌ์šฉํ•ด ์›๋ž˜์˜ ๋น„๊ต ํ•จ์ˆ˜๋ฅผ ๋‹ค์‹œ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.
const identity = field => value => dog => dog[field] === value;
const colorCheck = identity('์ƒ‰์ƒ');
const stateCheck = identity('์ง€์—ญ');

getDogNames(dogs, colorCheck('๊ฐˆ์ƒ‰'));
// ["์„€๋„"]
getDogNames(dogs, stateCheck('์บ”์ž์Šค'));
// ["์„€๋„"]
  • ํŠน์ •ํ•œ ์š”๊ตฌ ์‚ฌํ•ญ์ด ์žˆ๋Š” ํ•จ์ˆ˜๋ฅผ ๊ฐ€์ ธ์™€์„œ ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ๋‹ค๋ฅธ ๋น„๊ต๋ฅผ ํ•  ์ˆ˜ ์žˆ๋„๋ก ์ถ”์ƒํ™”๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.
  • ๋ถ€๋ถ„ ์ ์šฉ ํ•จ์ˆ˜๋ฅผ ๋ณ€์ˆ˜์— ํ• ๋‹นํ•  ์ˆ˜ ์žˆ๊ณ , ์ด ๋ณ€์ˆ˜๋ฅผ ๋ฐ์ดํ„ฐ๋กœ ์ „๋‹ฌํ•  ์ˆ˜๋„ ์žˆ๋‹ค
  • ์ฆ‰, ๊ฐ„๋‹จํ•œ ๋„๊ตฌ ๋ชจ์Œ์„ ์‚ฌ์šฉํ•ด์„œ ๋งค์šฐ ์ •๊ตํ•˜๊ฒŒ ๋น„๊ตํ•  ์ˆ˜ ์žˆ๋‹ค.
function allFilters(dogs, ...checks) {
return dogs
.filter(dog => checks.every(check => check(dog)))
.map(dog => dog['์ด๋ฆ„']);
}

allFilters(dogs, colorCheck('๊ฒ€์ •์ƒ‰'), stateCheck('์บ”์ž์Šค'));
// ["๋„๋‹ˆ"]

function anyFilters(dogs, ...checks) {
return dogs
.filter(dog => checks.some(check => check(dog)))
.map(dog => dog['์ด๋ฆ„']);
}

anyFilters(dogs, weightCheck(20), colorCheck('๊ฐˆ์ƒ‰'));
// ["๋งฅ์Šค", "์„€๋„"]

๐ŸŽฏ ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋กœ ๋ฌธ๋งฅ ํ˜ผ๋™์„ ํ”ผํ•˜๋ผ.โ€‹

  • ๋ฌธ๋งฅ์€ ํ•จ์ˆ˜ ๋˜๋Š” ํด๋ž˜์Šค์—์„œ this ํ‚ค์›Œ๋“œ๊ฐ€ ์ฐธ์กฐํ•˜๋Š” ๊ฒƒ์ด๊ธฐ๋„ ํ•˜๋‹ค.
  • ์œ ํšจ ๋ฒ”์œ„์™€ ๋ฌธ๋งฅ์€ ํŒŒ์•…ํ•˜๊ธฐ๊ฐ€ ์–ด๋ ต๊ธฐ๋„ ํ•˜์ง€๋งŒ, ํ˜ผ๋™ํ•˜๋Š” ๊ฐœ๋…์ด๊ธฐ๋„ ํ•˜๋‹ค.
  • ์œ ํšจ ๋ฒ”์œ„(scope)๋Š” ํ•จ์ˆ˜์™€ ์—ฐ๊ด€๋˜์–ด ์žˆ๊ณ , ๋ฌธ๋งฅ(context)์€ ๊ฐ์ฒด์™€ ์—ฐ๊ด€๋˜์–ด ์žˆ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.
const validator = {
message: '๋Š” ์œ ํšจํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.',
setInvalidMessage(field) {
return `${field}${this.message}`;
},
};

validator.setInvalidMessage('๋„์‹œ');
// ๋„์‹œ๋Š” ์œ ํšจํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • ์œ„ ์˜ˆ์ œ ์ฝ”๋“œ์—์„œ this.message๋Š” ํ•ด๋‹น ๊ฐ์ฒด์˜ ์†์„ฑ์„ ์ฐธ์กฐํ•œ๋‹ค.
  • ์ด๋ ‡๊ฒŒ ์ž‘๋™ํ•˜๋Š” ์ด์œ ๋Š” ๊ฐ์ฒด์—์„œ setInvalidMessage() ๋ฉ”์„œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋  ๋•Œ ํ•จ์ˆ˜์—์„œ this ๋ฐ”์ธ๋”ฉ์„ ์ƒ์„ฑํ•˜๋ฉด์„œ ํ•ด๋‹น ํ•จ์ˆ˜๊ฐ€ ๋‹ด๊ธด ๊ฐ์ฒด๋„ ๋ฌธ๋งฅ(context)์— ํฌํ•จ์‹œํ‚ค๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
  • ๊ฐ์ฒด์—์„œ this๋ฅผ ๋‹ค๋ฃฐ ๋•Œ๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ํฐ ๋ฌธ์ œ๊ฐ€ ์—†์ง€๋งŒ, ๊ฐ์ฒด์— ๋‹ด๊ธด ํ•จ์ˆ˜๋ฅผ ๋‹ค๋ฅธ ํ•จ์ˆ˜์˜ ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋กœ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ์—๋Š” ์ฃผ์˜๊ฐ€ ํ•„์š”ํ•˜๋‹ค.
  • ์˜ˆ๋ฅผ ๋“ค์–ด setTimeout(), setInterval() ๋ฉ”์„œ๋“œ๋‚˜ map(), filter() ๋ฉ”์„œ๋“œ ๋“ฑ ์ž์ฃผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฐ์—ด ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ์ด ํ•จ์ˆ˜๋“ค์€ ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋ฅผ ๋ฐ›์œผ๋ฉด์„œ ์ฝœ๋ฐฑ ํ•จ์ˆ˜์˜ ๋ฌธ๋งฅ๋„ ๋ณ€๊ฒฝํ•œ๋‹ค.
const validator = {
message: '๋Š” ์œ ํšจํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.',
setInvalidMessages(...fields) {
return fields.map(function (field) {
return `${field}${this.message}`;
});
},
};
  • ์—ฌ๊ธฐ์„œ ๋ฌธ์ œ๋Š” ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด TypeError ๋˜๋Š” undefined๋ฅผ ๋ฐ›๋Š”๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.
validator.setInvalidMessages('๋„์‹œ');
// ["๋„์‹œundefined"]
  • ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ๋งˆ๋‹ค ํ˜ธ์ถœ๋˜๋Š” ์œ„์น˜๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ this ๋ฐ”์ธ๋”ฉ์„ ๋งŒ๋“ ๋‹ค.
  • ์ฒ˜์Œ ์ž‘์„ฑํ–ˆ๋˜ setInvalidMessage()๋Š” ๊ฐ์ฒด๋ฅผ ๋ฌธ๋งฅ์œผ๋กœ ํ•ด์„œ ํ˜ธ์ถœ๋˜์—ˆ์ง€๋งŒ, ์—ฌ๊ธฐ์„œ๋Š” this์˜ ๋ฌธ๋งฅ์ด ํ•ด๋‹น ๊ฐ์ฒด์˜€๋‹ค.
  • map() ๋ฉ”์„œ๋“œ์— ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋กœ ์ „๋‹ฌํ•œ ๊ฒฝ์šฐ์—๋Š” map() ๋ฉ”์„œ๋“œ์˜ ๋ฌธ๋งฅ์—์„œ ํ˜ธ์ถœ๋˜๋ฏ€๋กœ ์ด ๊ฒฝ์šฐ์—๋Š” this ๋ฐ”์ธ๋”ฉ์ด validator ๊ฐ์ฒด๊ฐ€ ์•„๋‹ˆ๋‹ค.
  • ์ด๋•Œ์˜ ๋ฌธ๋งฅ์€ ์ „์—ญ ๊ฐ์ฒด๊ฐ€ ๋œ๋‹ค. ๋ธŒ๋ผ์šฐ์ €์—์„œ๋Š” window๊ฐ€, Node.js REPL ํ™˜๊ฒฝ์—์„œ๋Š” global์ด ๋œ๋‹ค.
  • ์ฆ‰, ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋กœ ์ „๋‹ฌ๋˜๋ฉด message ์†์„ฑ์— ์ ‘๊ทผํ•  ์ˆ˜ ์—†๊ฒŒ ๋œ๋‹ค.
  • ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•˜๋ฉด ์ด๋Ÿฐ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋Š” ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ this ๋ฐ”์ธ๋”ฉ์„ ์ƒˆ๋กœ ๋งŒ๋“ค์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์—, ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•ด์„œ map() ์ฝœ๋ฐฑ์„ ๋‹ค์‹œ ์ž‘์„ฑํ•˜๋ฉด ์˜๋„๋Œ€๋กœ ์ž‘๋™ํ•˜๊ฒŒ ๋œ๋‹ค.
const validator = {
message: '๋Š” ์œ ํšจํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.',
setInvalidMessages(...fields) {
return fields.map(field => {
return `${field}${this.message}`;
});
},
};

validator.setInvalidMessages('๋„์‹œ');
// ["๋„์‹œ๋Š” ์œ ํšจํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค."]
  • ๊ทธ๋ ‡์ง€๋งŒ this ๋ฌธ๋งฅ(context)์„ ์ง์ ‘ ์„ค์ •ํ•ด์•ผ ํ•  ๋•Œ๋„ ์žˆ๋‹ค.
  • ์˜ˆ๋ฅผ ๋“ค์–ด ๋‹ค์Œ ์˜ˆ์ œ ์ฝ”๋“œ์ฒ˜๋Ÿผ ์›๋ž˜์˜ setInvalidMessages() ๋ฉ”์„œ๋“œ๋ฅผ ๋ช…๋ช…๋œ ๋ฉ”์„œ๋“œ๊ฐ€ ์•„๋‹ˆ๋ผ ์†์„ฑ์— ํ• ๋‹นํ•œ ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋กœ ์ž‘์„ฑํ•œ ๊ฒฝ์šฐ์—๋Š” ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ํ• ๊นŒ??
const validator = {
message: '๋Š” ์œ ํšจํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.',
setInvalidMessages: field => `${field}${this.message}`,
};

validator.setInvalidMessages('๋„์‹œ');
// "๋„์‹œundefined"
  • ์ด ๊ฒฝ์šฐ์—๋Š” ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๊ฒŒ ๋œ๋‹ค. ํ˜„์žฌ ๊ฐ์ฒด์— ๋Œ€ํ•ด ์ƒˆ๋กœ์šด this ๋ฌธ๋งฅ ๋ฐ”์ธ๋”ฉ์„ ๋งŒ๋“ค์ง€ ์•Š์•˜๋‹ค.
  • ์ƒˆ๋กœ์šด ๋ฌธ๋งฅ์„ ๋งŒ๋“ค์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— ์ „์—ญ ๊ฐ์ฒด์— ๋ฐ”์ธ๋”ฉ ๋œ ๊ฒƒ์ด๋‹ค.
  • ์ •๋ฆฌํ•˜๋ฉด ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋Š” ์ด๋ฏธ ๋ฌธ๋งฅ์ด ์žˆ๊ณ  ๋‹ค๋ฅธ ํ•จ์ˆ˜ ๋‚ด๋ถ€์—์„œ ์ด ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๊ณ  ํ•  ๋•Œ ์œ ์šฉํ•˜๋‹ค.