λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
개발/Javascript

javascript ν•¨μˆ˜ν˜• ν”„λ‘œκ·Έλž˜λ°

by 1mj 2022. 2. 6.

λͺ©μ°¨

 

ν•¨μˆ˜ν˜• ν”„λ‘œκ·Έλž˜λ°

μ—°μ‚°ν•  λŒ€μƒμ΄ ν•¨μˆ˜κ°€ λ˜λŠ” ν”„λ‘œκ·Έλž˜λ° νŒ¨λŸ¬λ‹€μž„μœΌλ‘œ λ‚΄λΆ€ 데이터와 μƒνƒœλ₯Ό κ·ΈλŒ€λ‘œ 두고 μ—¬λŸ¬ ν•¨μˆ˜λ₯Ό μ‘°ν•©ν•˜μ—¬ μž‘μ—…μ„ μˆ˜ν–‰ν•˜λŠ” 방식이닀. 선언적 λ°©μ‹μœΌλ‘œ κ΅¬ν˜„λ˜λ©° 흐름 μ œμ–΄λ₯Ό λͺ…μ‹œμ μœΌλ‘œ κΈ°μˆ ν•˜μ§€ μ•Šκ³  λ‘œμ§μ„ ν‘œν˜„ν•œλ‹€.

 

ν•¨μˆ˜ν˜• ν”„λ‘œκ·Έλž˜λ° νŠΉμ§•

πŸ’‘ λͺ…λ Ήν˜•μ΄ μ•„λ‹Œ μ„ μ–Έν˜•μ΄λ‹€.

λͺ…λ Ήν˜• ν”„λ‘œκ·Έλž˜λ°μ€ 무엇을 μ–΄λ–»κ²Œ ν•  것인가에 μ§‘μ€‘ν•œλ‹€. ex) html, Lisp, Sql λ“±

// λ°°μ—΄ λ‚΄ μš”μ†Œλ₯Ό λŒ€λ¬Έμžλ‘œ λ°”κΎΈλŠ” μ½”λ“œ
// λ°°μ—΄ λ‚΄ μš”μ†Œλ₯Ό iλ₯Ό 증가해주며 ν•˜λ‚˜μ”© μ ‘κ·Όν•˜μ—¬ λŒ€λ¬Έμžλ‘œ λ°”κΎΈκ³  μƒˆ 배열에 λ‹΄μ•„μ€€λ‹€.
const arr = ['a', 'b', 'c'];
const result = new Array();
for (var i = 0; i < arr.length; i++) {
	result.push(arr[i].toUpperCase());
}
console.log(result);	// ["A", "B", "C"]

 

μ„ μ–Έν˜• ν”„λ‘œκ·Έλž˜λ°μ€ 무엇을 ν•  것인가에 μ§‘μ€‘ν•œλ‹€. ex) C, C++, Java, Pascal λ“±

// λ°°μ—΄ λ‚΄ μš”μ†Œλ₯Ό λŒ€λ¬Έμžλ‘œ λ°”κΎΈλŠ” μ½”λ“œ
// λ°°μ—΄ λ‚΄ λͺ¨λ“  μš”μ†Œμ— λŒ€λ¬Έμžλ‘œ λ°”κΎΈλŠ” ν•¨μˆ˜λ₯Ό μ μš©ν•œλ‹€.
const arr = ['a', 'b', 'c'];
console.log(arr.map(a => a.toUpperCase()));	// ["A", "B", "C"]

 

μ„ μ–Έν˜• 방식을 μ‚¬μš©ν•˜κΈ° μœ„ν•΄μ„œλŠ” λͺ…λ Ήν˜•μœΌλ‘œ μ–΄λ–»κ²Œ ν•  것인지 κ΅¬ν˜„λœ 것듀이 좔상화 λ˜μ–΄ μžˆμ–΄μ•Ό ν•œλ‹€.

즉, μ„ μ–Έν˜• 방식은 좔상화 λ˜μ–΄μžˆλŠ” λͺ…λ Ήν˜• 방식을 μ‚¬μš©ν•˜λŠ” 것이닀.

 

πŸ’‘ λΆ€μˆ˜νš¨κ³Ό(Side Effect)κ°€ μ—†λ‹€.

λΆ€μˆ˜νš¨κ³ΌλŠ” ν•¨μˆ˜κ°€ λ§Œλ“€μ–΄μ§„ λͺ©μ κ³Ό λ‹€λ₯Έ νš¨κ³Όλ‚˜ λΆ€μž‘μš©μ„ μ˜λ―Έν•œλ‹€.

λΆ€μˆ˜νš¨κ³Όκ°€ λ°œμƒν•˜λŠ” κ²½μš°λŠ” μ•„λž˜μ™€ κ°™λ‹€.

  • μ „μ—­λ²”μœ„μ—μ„œ λ³€μˆ˜, 속성, 자료ꡬ쑰λ₯Ό λ³€κ²½ν•  λ•Œ
  • thisλ₯Ό μ‚¬μš©ν•  λ•Œ
  • ν•¨μˆ˜μ˜ μ›λž˜ 인수 값을 λ³€κ²½ν•  λ•Œ
  • μ˜ˆμ™Έλ₯Ό μΌμœΌν‚¨ ν•¨μˆ˜κ°€ κ·ΈλŒ€λ‘œ μ˜ˆμ™Έλ₯Ό 던질 λ•Œ
// λΆˆμˆœν•¨μˆ˜: λ§€κ°œλ³€μˆ˜μ˜ 값을 직접 λ³€κ²½, λΆ€μˆ˜νš¨κ³Όλ‘œ κΈ°μ‘΄ λ°°μ—΄μ˜ κ°’ λ³€κ²½
var arr = ['a', 'b', 'c'];
var impure = (x) => {
  x.push('d');	// κΈ°μ‘΄ λ°°μ—΄ κ°’κΉŒμ§€ λ³€κ²½
  return x;
}
console.log(impure(arr));	// ["a", "b", "c", "d"]
console.log(arr);		// ["a", "b", "c", "d"]

// μˆœμˆ˜ν•¨μˆ˜: λ§€κ°œλ³€μˆ˜λ₯Ό λ³΅μ‚¬ν•œ 값을 λ³€κ²½
var arr = ['a', 'b', 'c'];
var pure = (x) => {
  newArr = [...x, 'd'];	// κΈ°μ‘΄ λ°°μ—΄ 값을 λ³€κ²½ν•˜μ§€ μ•Šκ³  펼침 μ—°μ‚°μžλ‘œ μƒˆλ‘œμš΄ 배열에 μΆ”κ°€
  return newArr;
}
console.log(pure(arr));		// ["a", "b", "c", "d"]
console.log(arr);		// ["a", "b", "c"]

 

λΆ€μˆ˜νš¨κ³Όκ°€ μ—†λŠ” ν•¨μˆ˜λŠ” μˆœμˆ˜ν•¨μˆ˜, μžˆλŠ” ν•¨μˆ˜λ₯Ό λΆˆμˆœν•¨μˆ˜κ°€ λœλ‹€.

μˆœμˆ˜ν•¨μˆ˜λŠ” μ™ΈλΆ€μ˜ μš”μΈμ„ 건듀이지 μ•Šμ€ 채 λ§€κ°œλ³€μˆ˜λ₯Ό λ°›μ•„ 정해진 λ‘œμ§λ§Œμ„ μ²˜λ¦¬ν•˜λŠ” ν•¨μˆ˜μ΄λ‹€.

μˆœμˆ˜ν•¨μˆ˜κ°€ 되렀면 μ•„λž˜μ˜ 쑰건을 λ§Œμ‘±ν•΄μ•Ό ν•œλ‹€.

  • ν•˜λ‚˜ μ΄μƒμ˜ 인자λ₯Ό λ°›μ•„μ•Ό ν•œλ‹€.
  • λ°˜ν™˜ 값이 λ°˜λ“œμ‹œ μ‘΄μž¬ν•΄μ•Ό ν•œλ‹€.
  • ν•¨μˆ˜ λ‚΄μ—μ„œ 인자λ₯Ό μ œμ™Έν•œ λ‹€λ₯Έ λ³€μˆ˜λ₯Ό μ‚¬μš©ν•˜λ©΄ μ•ˆλœλ‹€.
  • 동일 μž…λ ₯, 좜λ ₯이 보μž₯λ˜μ–΄μ•Ό ν•œλ‹€. (λ§€κ°œλ³€μˆ˜λ‘œ μž‘μ—…μ„ μ²˜λ¦¬ν•˜κ³  κ²°κ³Όλ₯Ό λ°˜ν™˜ν•΄μ•Ό ν•œλ‹€.)
// μˆœμˆ˜ν•¨μˆ˜X (인자둜 받지 μ•Šμ€ cond λ³€μˆ˜λ₯Ό ν•¨μˆ˜ μ•ˆμ—μ„œ μ‚¬μš©)
var arr = ['a', 'b', 'c'];
var cond = x => x.toUpperCase();
var ex = function(array) {
    return array.map(cond);
};
console.log(ex(arr));	// ["A", "B", "C"]

// μˆœμˆ˜ν•¨μˆ˜O
var ex = function(array, condition) {
  return array.map(condition);
};
var arr = ['a', 'b', 'c'];
var cond = x => x.toUpperCase();
console.log(ex(arr, cond));	// ["A", "B", "C"]

 

같은 μž…λ ₯에 λŒ€ν•΄ 항상 같은 좜λ ₯λ§Œμ„ 보μž₯ν•˜λ‹ˆ ν…ŒμŠ€νŠΈμ™€ 좔적이 쉽고 λ‹€λ₯Έ 곳에 영ν–₯을 주지 μ•Šμ•„ ν™œμš©ν•˜κΈ° μ‰½λ‹€λŠ” μž₯점이 μžˆλ‹€.

 

πŸ’‘ μƒνƒœ 변이λ₯Ό μ΅œμ†Œν™” ν•œλ‹€. (λΆˆλ³€μ„±)

μƒνƒœ λ³€μ΄λž€ λ©”λͺ¨λ¦¬μ— μ €μž₯된 값을 λ³€κ²½(λ³€μˆ˜μ˜ μž¬ν• λ‹Ή λ“±)ν•˜λŠ” 것을 μ˜λ―Έν•œλ‹€.λΆˆλ³€μ„±μ„ 지킀면 λ¬΄λΆ„λ³„ν•œ μƒνƒœμ˜ 변경을 막고 μƒνƒœμ˜ 변경을 μΆ”μ ν•˜κΈ° 쉽닀.

πŸ“š λ³€μˆ˜μ™€ λ©”λͺ¨λ¦¬
- μ„ μ–Έ: λ³€μˆ˜λ₯Ό 톡해 μ ‘κ·Όν•  수 μžˆλŠ” λ©”λͺ¨λ¦¬ 곡간 확보 ex) let num;
- ν• λ‹Ή: λ©”λͺ¨λ¦¬ 곡간에 κ°’ μ €μž₯ ex) num = 10;

μžλ°”μŠ€ν¬λ¦½νŠΈμ—μ„œ string, number, boolean νƒ€μž… 같은 μ›μ‹œ μžλ£Œν˜•μ˜ 경우 λ³€μˆ˜λ₯Ό μž¬ν• λ‹Ή ν•˜λ”λΌλ„ 원본 λ³€μˆ˜μ— λ‹΄κΈ΄ 값은 λ³€ν•˜μ§€ μ•Šκ³  λ‹€λ₯Έ λ©”λͺ¨λ¦¬ μ£Όμ†Œμ— λ³΅μ‚¬ν•΄μ„œ μ‚¬μš©ν•œλ‹€. (값에 μ˜ν•œ 호좜)
Array, Object νƒ€μž…κ³Ό 같은 객체듀은 원본 λ³€μˆ˜μ˜ λ©”λͺ¨λ¦¬ 값이 직접 λ³€κ²½λœλ‹€. (μ£Όμ†Œμ— μ˜ν•œ 호좜)
μƒνƒœ λ³€μ΄λž€ λ©”λͺ¨λ¦¬μ— μ €μž₯된 값이 λ³€κ²½λ˜λŠ” 것을 μ˜λ―Έν•˜λ©° λ™μ‹œμ— λΆˆλ³€μ„±μ„ 지킀지 μ•Šμ•˜λ‹€λŠ” μ˜λ―Έμ΄κΈ°λ„ ν•˜λ‹€.

 

πŸ’‘ μ°Έμ‘° 투λͺ…성을 가진닀.

ν‘œν˜„μ‹μ„ ν•΄λ‹Ή ν‘œν˜„μ‹μ˜ 결과둜 λŒ€μ²΄ν•΄λ„ 아무 영ν–₯이 μ—†λ‹€λ©΄ 참쑰에 투λͺ…ν•˜λ‹€κ³  μ–˜κΈ°ν•œλ‹€. 

예λ₯Ό λ“€μ–΄ 1 + 9 ν‘œν˜„μ‹μ„ ν•΄λ‹Ή ν‘œν˜„μ‹μ˜ 결과인 10으둜 μΉ˜ν™˜ν•΄λ„ μ•„λ¬΄λŸ° λ¬Έμ œκ°€ μ—†κΈ° λ•Œλ¬Έμ— 참쑰에 투λͺ…ν•˜λ‹€.

function add(a, b) {
  return a + b;
}
function multiple(a, b) {
  return a * b;
}
// multiple(1, 2)λ₯Ό 2둜 λŒ€μ²΄ν•΄λ„ 영ν–₯ μ—†μŒ
console.log(add(5, multiple(1, 2)));

function add(a, b) {
	var result = a + b;
	console.log('result: ' + result);
	return result;
}
// add(3, 4)λ₯Ό 12둜 λ°”κΎΈλ©΄ κ²°κ³Όκ°€ 닀름
console.log(add(3, 4));

 

ν•¨μˆ˜ν˜• ν”„λ‘œκ·Έλž˜λ° 원칙

  • μž…μΆœλ ₯이 μˆœμˆ˜ν•΄μ•Ό ν•œλ‹€.
  • 뢀산물이 μ—†μ–΄μ•Ό ν•œλ‹€.
  • ν•¨μˆ˜μ™€ 데이터λ₯Ό μ€‘μ μœΌλ‘œ 생각해야 ν•œλ‹€.

 

ν•¨μˆ˜ν˜• ν”„λ‘œκ·Έλž˜λ° 기법

μ•Œμ•„λ‘˜ 것

μžλ°”μŠ€ν¬λ¦½νŠΈμ—μ„œ ν•¨μˆ˜λ₯Ό λ³€μˆ˜μ— ν• λ‹Ήν•  수 μžˆλ‹€.

// λ³€μˆ˜μ— ν•¨μˆ˜ ν• λ‹Ή
const add = function(a, b) {
  return a + b;
}
add(1, 3);	// 4

// ν•¨μˆ˜λ₯Ό λ‹€λ₯Έ λ³€μˆ˜μ— λ„˜κΈ°κΈ°
const copyAdd = add;
copyAdd(3, 2);	// 5

 

μžλ°”μŠ€ν¬λ¦½νŠΈμ—μ„œ ν•¨μˆ˜λ₯Ό νŒŒλΌλ―Έν„°λ‘œ λ„˜κΈΈ 수 μžˆλ‹€.

function hello() {
	return 'hello';
}

// ν•¨μˆ˜λ₯Ό νŒŒλΌλ―Έν„°λ‘œ λ°›λŠ” ν•¨μˆ˜
function print(func) {
  console.log(func);	// function hello() { return 'hello'; }
	console.log(func());	// hello
}

// ν•¨μˆ˜λ₯Ό νŒŒλΌλ―Έν„°λ‘œ λ„˜κΈ°κΈ°
print(hello);

 

κ³ μ°¨ν•¨μˆ˜ (HOF, Higher-Order Function)

ν•¨μˆ˜λ₯Ό λ§€κ°œλ³€μˆ˜λ‘œ μ‚¬μš©ν•˜κ±°λ‚˜ ν•¨μˆ˜λ₯Ό λ°˜ν™˜ν•˜λŠ” ν•¨μˆ˜μ΄λ‹€.

값을 μž…λ ₯λ°›κ³  λ‘œμ§μ„ μ²˜λ¦¬ν•˜μ—¬ λ°˜ν™˜ν•˜λŠ” λ‘œμ§μ„ κ°μΆ”λŠ” 좔상화 단계(ν•¨μˆ˜)μ—μ„œ ν•œ 단계 더 λ†’μ—¬ ν•¨μˆ˜λ₯Ό 전달받아 μ²˜λ¦¬ν•˜λ―€λ‘œ 높은 좔상화 μˆ˜μ€€μ„ κ°€μ§„λ‹€λŠ” 이점이 μžˆλ‹€.

// ν•¨μˆ˜λ₯Ό λ§€κ°œλ³€μˆ˜λ‘œ μ‚¬μš©ν•˜λŠ” ν•¨μˆ˜
function foo(f) {
  f();
}

// ν•¨μˆ˜λ₯Ό λ°˜ν™˜ν•˜λŠ” ν•¨μˆ˜
function foo() {
  return function() {};
}

 

μžλ°”μŠ€ν¬λ¦½νŠΈμ— 기본적으둜 λ‚΄μž₯된 κ³ μ°¨ ν•¨μˆ˜ 쀑 많이 μ‚¬μš©λ˜λŠ” ν•¨μˆ˜λ“€μ΄λ‹€.

ν•¨μˆ˜λͺ… κΈ°λŠ₯
forEach 각 μš”μ†Œμ— ν•¨μˆ˜λ₯Ό 적용(μƒˆλ‘œμš΄ 배열을 λ°˜ν™˜ν•˜μ§€ μ•ŠμŒ)
filter νŠΉμ • 쑰건을 λ§Œμ‘±ν•˜λŠ” μš”μ†Œλ₯Ό μƒˆλ‘œμš΄ λ°°μ—΄λ‘œ λ°˜ν™˜
find λ°°μ—΄μ˜ μš”μ†Œλ₯Ό μˆœνšŒν•˜λ©΄μ„œ 쑰건에 μΌμΉ˜ν•˜λŠ” μš”μ†Œμ˜ 값을 μ¦‰μ‹œ λ°˜ν™˜
map 각 μš”μ†Œμ— ν•¨μˆ˜λ₯Ό μ μš©ν•œ 값을 μƒˆλ‘œμš΄ λ°°μ—΄λ‘œ λ°˜ν™˜
reduce 각 μš”μ†Œμ— λŒ€ν•΄ reducer ν•¨μˆ˜λ₯Ό μ‹€ν–‰ν•˜κ³  ν•˜λ‚˜μ˜ κ²°κ³Ό 값을 λ°˜ν™˜
sort μ •λ ¬

 

const arr1 = ['a', 'b', 'c'];
const arr2 = ['aria', 'brick', 'cathy'];
const arr3 = [-1, 0, 4, -2, 3];
const arr5 = [1, 2, 3, 4, 5];
const arr6 = [2, 1, 4, 5, 3];

// 1. forEach
// 콜백 ν•¨μˆ˜ λ‚΄μ—μ„œ 처리 ν›„ !λ°˜ν™˜! λΆˆκ°€(이런 경우 map μ‚¬μš©)
arr1.forEach(function(element, index){
    console.log(index + ': ' + element);	// 0: a, 1: b, 2: c
});

// ν™”μ‚΄ν‘œ ν•¨μˆ˜ 이용
arr1.forEach(element => console.log(element));	// a, b, c


// 2. filter
let result = arr2.filter(element => element.startsWith('a'));
console.log(result);	// ["aria"]


// 3. find
// 0 이상을 λ§Œμ‘±ν•˜λŠ” 첫 번째 μš”μ†Œ λ°˜ν™˜
result = arr3.find(element => element > 0);
console.log(result);	// 4

// λ§Œμ‘±ν•˜λŠ” μš”μ†Œκ°€ μ—†μœΌλ©΄ undefined λ°˜ν™˜
result = arr3.find(element => element > 10);
console.log(result);	// undefined


// 4. map
// ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•œ κ²°κ³Όλ₯Ό μƒˆλ‘œμš΄ λ°°μ—΄λ‘œ λ°˜ν™˜
result = arr1.map(x => x.toUpperCase());
console.log(result);	// ["A", "B", "C"]


// 5. reduce
const reducer = (previousValue, currentValue) => previousValue + currentValue;
console.log(arr5.reduce(reducer));	// 15(1+2+3+4+5)


// 6. sort
arr6.sort(function(a, b) {
  return a - b;
});
console.log(arr6);	// [1, 2, 3, 4, 5]

 

ν™”μ‚΄ν‘œ ν•¨μˆ˜ (Arrow Function)

function λŒ€μ‹  ν™”μ‚΄ν‘œ(=>)λ₯Ό μ΄μš©ν•˜μ—¬ κ°„λ‹¨νžˆ ν•¨μˆ˜λ₯Ό ν‘œν˜„ν•˜λŠ” 방법이닀.

 

πŸ”Ž ν™”μ‚΄ν‘œ ν•¨μˆ˜ κΈ°λ³Έ

// ν™”μ‚΄ν‘œ ν•¨μˆ˜ 이용(μ•„λž˜ ν•¨μˆ˜μ˜ μΆ•μ•½ν˜•)
const func = (arg1, arg2, ...argN) => expression

// κΈ°λ³Έ ν•¨μˆ˜
const func = function(arg1, arg2, ...argN) {
    return expression;
};

 

πŸ”Ž μƒλž΅ κ°€λŠ₯ν•œ 것

// λ§€κ°œλ³€μˆ˜κ°€ ν•˜λ‚˜μΈ 경우 인자 μ†Œκ΄„ν˜Έ μƒλž΅ κ°€λŠ₯
singleParam => { statement }

// λ§€κ°œλ³€μˆ˜κ°€ μ—†λŠ” 경우 인자 μ†Œκ΄„ν˜Έ ν•„μš”

() => { statement }

// 본문이 ν•œ 쀄인 경우 λ³Έλ¬Έ μ€‘κ΄„ν˜Έ μƒλž΅ κ°€λŠ₯

const sum = (a, b) => a + b;

// 본문이 μ—¬λŸ¬ 쀄인 경우
const sum = (a, b) => {
    const result = a + b;
    return result; // 본문이 μ—¬λŸ¬ 쀄인 경우 return μ§€μ‹œμžλ‘œ κ²°κ³Ό 값을 κΌ­ λ°˜ν™˜ν•΄μ•Ό ν•œλ‹€.
};

 

ν΄λ‘œμ € (Closure)

μ™ΈλΆ€ ν•¨μˆ˜μ— μ ‘κ·Όν•  수 μžˆλŠ” λ‚΄λΆ€ ν•¨μˆ˜μ˜ μ›λ¦¬λ‘œ λ‚΄λΆ€ν•¨μˆ˜μ—μ„œ μ™ΈλΆ€ν•¨μˆ˜ μŠ€μ½”ν”„μ— μ„ μ–Έλœ λ³€μˆ˜μ— μ ‘κ·Ό κ°€λŠ₯ν•˜μ§€λ§Œ κ·Έ λ°˜λŒ€λŠ” λΆˆκ°€λŠ₯ν•˜λ‹€.

function outerFunction() {
  let msg = '';	// μžμœ λ³€μˆ˜λΌκ³  뢀름
  return function innerFunction(newMsg) { // ν΄λ‘œμ €
  	msg = msg + newMsg;
    return msg;
  }
}

// test λ³€μˆ˜λŠ” innerFunction ν•¨μˆ˜ μ°Έμ‘°
// outerFunction의 μ‹€ν–‰ μ»¨ν…μŠ€νŠΈλŠ” μ†Œλ©Έλ¨
let test = outerFunction();
test('po'); // "po";
test('ta'); // "pota";
test('to'); // "potato";

 

λ³€μˆ˜ msgλŠ” ν•¨μˆ˜μ˜ μ‹€ν–‰ μ»¨ν…μŠ€νŠΈκ°€ μ’…λ£Œλ˜λ©΄ μ™ΈλΆ€μ—μ„œ μ ‘κ·Όν•  수 μ—†λ‹€. ν•¨μˆ˜ λ°–μ—μ„œλ„ msg λ³€μˆ˜λ₯Ό μ‚¬μš©ν•˜κΈ° μœ„ν•΄μ„œλŠ” ν΄λ‘œμ €λ₯Ό μ‚¬μš©ν•˜λ©΄ λœλ‹€. ν΄λ‘œμ €λŠ” λ°˜ν™˜λœ λ‚΄λΆ€ν•¨μˆ˜κ°€ μžμ‹ μ΄ μ„ μ–Έλ˜μ—ˆμ„ λ•Œμ˜ ν™˜κ²½(μŠ€μ½”ν”„)을 κΈ°μ–΅ν•˜κ³  κ·Έ μŠ€μ½”ν”„ λ°–μ—μ„œ ν˜ΈμΆœλ˜μ–΄λ„ μ ‘κ·Όν•  수 μžˆλŠ” 원리λ₯Ό λ§ν•œλ‹€. κΌ­ λ‚΄λΆ€ ν•¨μˆ˜λ₯Ό λ°˜ν™˜ν•˜λŠ” κ°œλ… μžμ²΄κ°€ ν΄λ‘œμ €κ°€ μ•„λ‹ˆλ©° μ•„λž˜μ™€ 같이 μ‚¬μš©ν•  μˆ˜λ„ μžˆλ‹€.

 

let globalFunction;
{
  let msg = '';
  globalFunction = function(newMsg) { // ν΄λ‘œμ €
  	msg = msg + newMsg;
    return msg;
  }
}

globalFunction('po'); // "po";
globalFunction('to'); // "pota";
globalFunction('to'); // "potato";

 

ν΄λ‘œμ €λŠ” ν˜„μž¬ μƒνƒœλ₯Ό κΈ°μ–΅ν•˜κ³  λ³€κ²½λœ μ΅œμ‹  μƒνƒœλ₯Ό μœ μ§€ν•œλ‹€λŠ” μ μ—μ„œ μœ μš©ν•˜κ²Œ μ‚¬μš©λ  수 μžˆλ‹€.(λ³€μˆ˜κ°€ μ†Œλ©Έλ˜μ§€ μ•Šκ³  λ§ˆμ§€λ§‰ μƒνƒœλ₯Ό κΈ°μ–΅ν•œλ‹€λŠ” 점)

μ „μ—­ λ³€μˆ˜μ˜ μ‚¬μš©μ„ 쀄이고 μ½”λ“œ μž¬μ‚¬μš©μ— μš©μ΄ν•˜λ‹€λŠ” μž₯점이 μžˆμ§€λ§Œ var λ³€μˆ˜λ₯Ό μ‚¬μš©ν•˜λŠ” κ²½μš°μ— μœ μ˜ν•΄μ•Ό ν•œλ‹€.

 

 

컀링 (Currying)

인자λ₯Ό μ—¬λŸ¬ 개 λ°›λŠ” ν•¨μˆ˜λ₯Ό λΆ„λ¦¬ν•˜μ—¬ 인자λ₯Ό ν•˜λ‚˜μ”©λ§Œ λ°›λŠ” ν•¨μˆ˜μ˜ 체인으둜 λ§Œλ“œλŠ” 방법이닀.

function uncurrying(greeting, name){
    console.log(greeting + ", " + name);
}

function currying(greeting){
    return function(name){
        console.log(greeting + ", " + name);
    }
}

// 컀링 없이 νŒŒλΌλ―Έν„° 두 개λ₯Ό λ°›λŠ” 경우
uncurrying("hello", "anna");	// "hello, anna"

// 컀링
var hello = currying("hello");
hello("jane");		// "hello, jane" 
hello("angela");	// "hello, angela"

 

 

// 컀링 λ³€ν™˜μ„ ν•˜λŠ” ν•¨μˆ˜
function curry(f) {
  return function(x) {
    return function(y) {
      return f(x, y);
    };
  };
}

// 컀링 λ³€ν™˜μ„ ν•˜λŠ” ν•¨μˆ˜λ₯Ό ν™”μ‚΄ν‘œ ν•¨μˆ˜λ‘œ ν‘œν˜„ν•œ 것 (μœ„ curry ν•¨μˆ˜μ™€ 동일)
// const curry = f => x => y => f(x, y);

// f에 μ „λ‹¬λœ ν•¨μˆ˜: (a, b) => a * b
const curried = curry((a, b) => a * b);
// a에 10, b에 5전달
curried(10)(5); // 50

 

μœ„ μ˜ˆμ‹œμ²˜λŸΌ 같은 인자λ₯Ό μ—¬λŸ¬ 번 전달해야 ν•˜λŠ” 경우 μœ μš©ν•˜κ²Œ μ‚¬μš©λ  수 μžˆλ‹€.

컀링 ν•¨μˆ˜μ—μ„œλŠ” 인자의 μˆœμ„œλ₯Ό 신경써야 ν•˜λŠ”λ°, κ°€μž₯ λ¨Όμ € λ°›λŠ” 인자(μ™ΈλΆ€ ν•¨μˆ˜)λŠ” λ³€ν•˜μ§€ μ•Šκ³  κ°€μž₯ λ‚˜μ€‘μ— λ°›λŠ” 인자(λ‚΄λΆ€ ν•¨μˆ˜)λŠ” κ°€λ³€μ μœΌλ‘œ κ΅¬μ„±ν•˜λŠ” 것이 μ’‹λ‹€.

 

 

참고자료 및 좜처 πŸ™‡‍♂️

https://chifuyu.tistory.com/35?category=1174105 

https://yeongseungjeong.tistory.com/37

https://helloworldjavascript.net/pages/255-fp.html

 

λŒ“κΈ€