Higher Order Functions in JavaScript - Lee-hyuna/33-js-concepts-kr GitHub Wiki

Javascript의 κ³ μ°¨ ν•¨μˆ˜

원문: Higher Order Functions in JavaScript

κ³ μ°¨ ν•¨μˆ˜λŠ” μ²˜μŒμ—” κ²λ‚˜μ§€λ§Œ λ°°μš°λŠ” 건 어렡지 μ•Šλ‹€. κ³ μ°¨ ν•¨μˆ˜λŠ” λ‹¨μˆœνžˆ ν•¨μˆ˜λ₯Ό 맀개 λ³€μˆ˜λ‘œ λ°›κ±°λ‚˜ ν•¨μˆ˜λ₯Ό 결과둜 λ°˜ν™˜ν•˜λŠ” ν•¨μˆ˜μ΄λ‹€. JavaScriptμ—μ„œ κ°€μž₯ μœ μš©ν•œ νŒ¨ν„΄ 쀑 ν•˜λ‚˜μ΄λ©° ν•¨μˆ˜ν˜• ν”„λ‘œκ·Έλž˜λ° μ—μ„œ 특히 μ€‘μš”ν•˜λ‹€.

λ¨Όμ € μžλ°”μŠ€ν¬λ¦½νŠΈμ˜ νŽΈλ¦¬ν•œ Array.map() λ©”μ„œλ“œλ₯Ό μ΄μš©ν•œ μ˜ˆμ œλΆ€ν„° ν•˜κ² λ‹€. 각각 name 속성을 가진 객체 배열이 μžˆλ‹€κ³  κ°€μ • ν•΄ 보자:

const characters = [
  {name: 'Han Solo'},
  {name: 'Luke SkyWalker'},
  {name: 'Leia Organa'}
];

map λ©”μ„œλ“œλ₯Ό μ΄μš©ν•˜μ—¬ 각 name듀을 μ½˜μ†”μ— 찍어 보자. (μ‹€μ œ 예제).

// ES6 syntax
const names = characters.map(character => character.name);
console.log(names);  // "Han Solo" "Luke SkyWalker" "Leia Organa"

// ES5 syntax
var names2 = characters.map(function(character) { return character.name; });  console.log(names2);  // "Han Solo" "Luke SkyWalker" "Leia Organa"

map λ©”μ„œλ“œ (일λͺ… ν•¨μˆ˜)κ°€ λ‹€λ₯Έ ν•¨μˆ˜λ₯Ό 맀개 λ³€μˆ˜λ‘œ λ°›μ•„ μ‚¬μš©ν•˜λŠ” 것을 λ³΄μ•˜λŠ”κ°€ ? map λ©”μ„œλ“œλŠ” κ³ μ°¨ ν•¨μˆ˜μ— λŒ€ν•œ μ •μ˜μ— μ•Œλ§žμ€ μ˜ˆμ΄λ‹€. κ³ μ°¨ ν•¨μˆ˜λŠ” κ·Έλ ‡κ²Œ μ–΄λ €μš΄ 것이 μ•„λ‹ˆλ‹€. μ‹€μ œλ‘œ, μš°λ¦¬λŠ” map λ©”μ„œλ“œκ°€ κ³ μ°¨ ν•¨μˆ˜λΌλŠ” 것을 깨닫지 λͺ»ν•˜κ³  항상 μ‚¬μš©ν–ˆμ„ μˆ˜λ„ μžˆλ‹€.

이제 ν•¨μˆ˜ν˜• ν”„λ‘œκ·Έλž˜λ°μ—μ„œ λ°€μ ‘ν•˜κ²Œ κ΄€λ ¨λœ λ‹€λ₯Έ κ°œλ…μ„ μ‚΄νŽ΄λ³΄μž. ν•¨μˆ˜ ꡬ성(Function composition) 은 κ³ μ°¨ ν•¨μˆ˜λΌλŠ” κ°œλ…μ„ μ·¨ν•˜κ³  맀우 κ°•λ ₯ν•œ λ°©μ‹μœΌλ‘œ μž‘μ„±ν•  수 μžˆλ‹€. μž‘κ³  μ§‘μ€‘λœ ν•¨μˆ˜λ“€μ„ μ‘°ν•©ν•˜μ—¬ λ³΅μž‘ν•œ κΈ°λŠ₯을 λ§Œλ“€ 수 μžˆλ‹€. μ΄λŸ¬ν•œ "λΉŒλ”© 블둝"κΈ°λŠ₯을 μž‘κ²Œ μœ μ§€ν•˜λ©΄ ν…ŒμŠ€νŠΈν•˜κΈ°κ°€ 쉽고 λΉ„μš©μ„ 적게 λ“€κ²Œ ν•˜λ©°, μž¬μ‚¬μš© ν•  수 μžˆλ‹€.

이것이 μ–΄λ–»κ²Œ λ³΄μ΄λŠ”μ§€ 보렀면 λ‹€λ₯Έ 예λ₯Ό μ‚΄νŽ΄ 보자. μ²˜μŒμ— μ½”λ“œκ°€ μ•½κ°„ ν˜Όλž€μŠ€λŸ¬μ›Œλ„ κ±±μ •ν•˜μ§€λ§ˆλΌ. μž μ‹œ 후에 μ½”λ“œλ₯Ό 천천히 μ‚΄νŽ΄λ³Ό 것이닀. λ¨Όμ € ES6 버전뢀터 μ‹œμž‘ν•΄ 보자.

// ES6 version
const characters =  [
	{name:  'Luke Skywalker', img:  'http://example.com/img/luke.jpg', species:  'human'},
	{name:  'Han Solo', img:  'http://example.com/img/han.jpg', species:  'human'},
	{name:  'Leia Organa', img:  'http://example.com/img/leia.jpg', species:  'human'},
	{name:  'Chewbacca', img:  'http://example.com/img/chewie.jpg', species:  'wookie'}
];

const humans = data => data.filter(character => character.species ===  'human');
const images = data => data.map(character => character.img);
const compose = (func1, func2) => data => func2(func1(data));
const displayCharacterImages = compose(humans, images);

console.log(displayCharacterImages(characters));

/* 
Logs out the following array
	["http://example.com/img/luke.jpg",
	 "http://example.com/img/han.jpg",
	 "http://example.com/img/leia.jpg"
	 ]
*/

그리고 이제 같은 μ½”λ“œ 의 ES5 버전을 보자.

// ES5 version
var characters =  [ 
	{name:  'Luke Skywalker', img:  'http://example.com/img/luke.jpg', species:  'human'},
	{name:  'Han Solo', img:  'http://example.com/img/han.jpg', species:  'human'},
	{name:  'Leia Organa', img:  'http://example.com/img/leia.jpg', species:  'human'},
	{name:  'Chewbacca', img:  'http://example.com/img/chewie.jpg', species:  'wookie'}
];
var humans = function(data) {
	return data.filter(function(character) {
		return character.species ===  'human';
	})
}
var images = function(data) {
	return data.map(function(character) {
		return character.img;
	})
}  
function compose(func1, func2) {
	return function(data) {
		return  func2(func1(data));
	};
} 
var displayCharacterImages =  compose(humans, images);  

console.log(displayCharacterImages(characters));
/* 
Logs out the following array
	["http://example.com/img/luke.jpg",
	 "http://example.com/img/han.jpg",
	 "http://example.com/img/leia.jpg"
	 ]
*/

자, 이것을 λ‹¨κ³„λ³„λ‘œ μ‚΄νŽ΄λ³΄λ©° μ–΄λ–»κ²Œ μœ μš©ν•œ 지 μ•Œμ•„λ³΄μž. μ„€λͺ…은 κ°€λŠ₯ν•œ μΉœμˆ™ν•œ ES5 예제λ₯Ό μ‚¬μš©ν•  것이닀.

  1. 두 번째 μ€„μ—μ„œ 객체 배열을 μ„ μ–Έν•œλ‹€.(characters). API 호좜의 결과둜써 μ΄λŸ¬ν•œ 데이터λ₯Ό μˆ˜μ‹ ν•˜κ³  μž‘μ—…ν•˜λŠ” 것은 일반 적이닀.

  2. 그런 λ‹€μŒ μš°λ¦¬κ°€ ν˜ΈμΆœν•  첫 번째 ν•¨μˆ˜( humans)λ₯Ό μ„ μ–Έν•œλ‹€.이 ν•¨μˆ˜μ— λŒ€ν•΄ μ•Œμ•„μ•Όν•  것은 순수 ν•¨μˆ˜λΌλŠ” 것 이닀. 즉, λ™μΌν•œ μž…λ ₯이 주어지면 항상 λ™μΌν•œ 좜λ ₯을 λ°˜ν™˜ν•œλ‹€. ν•¨μˆ˜ν˜• ν”„λ‘œκ·Έλž˜λ°μ˜ 핡심 κ°œλ…μ΄λ‹€. 이λ₯Ό 톡해 ν•¨μˆ˜λ₯Ό μ‰½κ²Œ ν…ŒμŠ€νŠΈ, λ¦¬νŒ©ν† λ§ ν•  수 μžˆλ‹€.

  3. 그런 λ‹€μŒ 두 번째 ν•¨μˆ˜(images)λ₯Ό μ„ μ–Έν•œλ‹€. . map ν•¨μˆ˜ μ•ˆμ— 전달 된 콜백 ν•¨μˆ˜λ₯Ό μ‚΄νŽ΄λ΄λΌ. μ•„λž˜μ—μ„œ μ„€λͺ…ν•  것이닀.

function(character) {
	return character.img;
}

μ½”λ“œλ₯Ό 더 μ‰½κ²Œ 따라할 수 μžˆλ„λ‘ "character"λ₯Ό μ‚¬μš©ν–ˆμœΌλ‚˜ λŒ€μ‹  "item"λ˜λŠ” 이와 μœ μ‚¬ν•œ 것 μ΄λ¦„μœΌλ‘œ μ‚¬μš©ν•˜λ©΄ ν•¨μˆ˜κ°€ μ½”λ“œμ˜ λ‚˜λ¨Έμ§€ λΆ€λΆ„μœΌλ‘œ λΆ€ν„° μ™„μ „νžˆ λΆ„λ¦¬λ˜μ—ˆλŠ”μ§€ 확인할 수 μžˆλ‹€. img 속성 μ΄μžˆλŠ” λͺ¨λ“  객체 배열에 μ‚¬μš©ν•  수 μžˆλ‹€. μ½”λ“œ μž¬μ‚¬μš©μ„ ν•  수 μžˆλ‹€λŠ” 것이닀!

  1. λ‹€μŒμœΌλ‘œ 두 ν•¨μˆ˜λ₯Ό 맀개 λ³€μˆ˜λ‘œ λ°›κ³  λ‹€λ₯Έ ν•¨μˆ˜λ₯Ό λ°˜ν™˜ν•˜λŠ” κ³ μ°¨ ν•¨μˆ˜μΈ compose κ°€ μžˆλ‹€. 이 ν•¨μˆ˜λŠ” λ˜ν•œ μ™Όμͺ½μ—μ„œ 였λ₯Έμͺ½μœΌλ‘œ 호좜 된 두 ν•¨μˆ˜μ˜ κ²°κ³Όλ₯Ό κ²°ν•©ν•˜κΈ° μœ„ν•΄ μž¬μ‚¬μš© 될 수 μžˆλ‹€. 데이터λ₯Ό μ „λ‹¬ν•˜κ³  ν•¨μˆ˜κ°€ ν•„μš”ν•œ λ°©μ‹μœΌλ‘œ λ³€ν™˜ν•˜λ©΄ λœλ‹€.

  2. μš°λ¦¬λŠ” λ‹€μŒ composeν•¨μˆ˜μ— humans κ³Ό images ν•¨μˆ˜λ₯Ό μ „λ‹¬ν•˜μ—¬ 호좜 ν•  것이고, λ³€μˆ˜displayCharacterImages에 κ²°κ³Όλ₯Ό ν• λ‹Ήν•  것이닀 . μ§€κΈˆ displayCharacterImages에 값을 λ‘œκΉ…ν•˜λ©΄, compose에 μ˜ν•΄ λ°˜ν™˜λœ λ‚΄λΆ€ ν•¨μˆ˜λ₯Ό λ³Ό 수 μžˆλ‹€.

function (data) {
	return func2(func1(data));
}
  1. λ§ˆμΉ¨λ‚΄ displayCharacterImagesλ₯Ό ν˜ΈμΆœν•˜λ©΄ μ „λ‹¬λœ characters 배열은 func1(humans)에 전달 될 것이닀. 이 ν•¨μˆ˜μ˜ λ°°μ—΄μ˜ κ²°κ³Ό 값은 였직 "human" 문자λ₯Ό ν¬ν•¨ν•œ 것듀 만 λ°˜ν™˜ν•œλ‹€.(츄이 λ―Έμ•ˆ!) 그리고 이 κ²°κ³Ό 값이 데이터 μ„ΈνŠΈμ—μ„œ human μΊλ¦­ν„°μ˜ 이미지 속성을 λ°˜ν™˜ν•˜λŠ” func2(images)ν•¨μˆ˜λ‘œ μ „λ‹¬λœλ‹€. 이 ν•¨μˆ˜λ₯Ό μ΄μš©ν•΄μ„œ 팬 μ‚¬μ΄νŠΈμ˜ 일뢀에 ν•΄λ‹Ή 이미지λ₯Ό ν‘œμ‹œ ν•΄λ³΄λŠ” 것을 상상해 봐라.

λ‹€ν–‰μŠ€λŸ½κ²Œλ„ κ³ μ°¨ ν•¨μˆ˜μ— λŒ€ν•œ 주제λ₯Ό μ†Œκ°œν•˜κ³  μž‘μ€ ν•¨μˆ˜λ₯Ό κ²°ν•©ν•˜μ—¬ λ³΅μž‘ν•œ λ™μž‘μ„ λ§Œλ“œλŠ” 방법에 λŒ€ν•΄ ν–ˆλ‹€. 이것을 μ¦‰μ‹œ μ΄ν•΄ν•˜μ§€ λͺ»ν•΄λ„ κ±±μ •ν•˜μ§€ 말아라. 이것은 ν•¨μˆ˜ν˜• ν”„λ‘œκ·Έλž˜λ°μ˜ μΌλΆ€μ΄μ§€λ§Œ, 일단 μ‚¬μš©ν•  수 있게 λœλ‹€λ©΄ 맀우 κ°•λ ₯ν•˜κ³  였λ₯˜κ°€ 적은 μœ μ—°ν•œ μ½”λ“œλ₯Ό μž‘μ„±ν•  수 μžˆλ‹€.

μΆ”κ°€ 자료

ν•¨μˆ˜ν˜• ν”„λ‘œκ·Έλž˜λ°μ— λŒ€ν•΄ 더 배우고 μ‹Άλ‹€λ©΄ λͺ‡ 가지 쒋은 μžλ£Œκ°€ μžˆλ‹€. 첫 λ²ˆμ§ΈλŠ” Anjana Vakil의 컨퍼런슀 λ°œν‘œ 인 Learning Functional Programming with JavaScript이닀. Mattias Petter Johansson (mpj)의 ν›Œλ₯­ν•˜κ³  μž¬λ―ΈμžˆλŠ” λΉ„λ””μ˜€ νŠœν† λ¦¬μ–Ό μ‹œλ¦¬μ¦ˆλ„ μžˆλ‹€. λ§ˆμ§€λ§‰μœΌλ‘œ 기사 ν˜•μ‹μ„ μ„ ν˜Έν•˜λŠ” μ‚¬λžŒλ“€μ—κ²ŒλŠ” Raja Rao의 Functional Programming In JavaScript β€” With Practical Examplesκ³Ό Peleke Sengstack의 How to Use Map, Filter, & Reduce in JavaScript이 μžˆλ‹€.

⚠️ **GitHub.com Fallback** ⚠️