함수형 프로그래밍
자바스크립트는 멀티 패러다임 언어로, 객체지향과 함수형 프로그래밍 스타일을 모두 지원합니다. 자바스크립트는 함수를 일급 객체로 취급하는 언어로, 이러한 특성 덕분에 함수형 프로그래밍을 자연스럽게 지원합니다.
1. 일급 함수
자바스크립트에서 함수는 일급 객체로, 변수에 할당하거나 다른 함수의 인자로 전달할 수 있습니다.
2. 고차 함수
Array 객체의 내장 메서드들(map, filter, reduce 등)은 함수형 프로그래밍의 대표적 예입니다.
3. 클로저
클로저는 함수가 자신이 생성된 환경의 변수를 기억하고 접근할 수 있는 기능으로, 함수형 프로그래밍에서 상태를 캡슐화하는 데 사용됩니다.
4. 불변성
ES6부터 도입된 const와 스프레드 연산자(...)는 불변성을 구현하는 데 도움이 됩니다.
이터러블 / 이터레이터 프로토콜
ES6에서 도입된 이터러블/이터레이터 프로토콜은 컬렉션 데이터를 순회하는 표준 방법을 제공합니다. 이 프로토콜은 함수형 프로그래밍과 결합하여 더욱 강력한 데이터 처리 패턴을 가능하게 합니다.
자바스크립트에서 이터러블 프로토콜을 잘("well-formed") 따르고 있다면 for... of, 전개 연산자, 구조 분해, 나머지 연산자 등을 사용할 수 있다.
이터러블(Iterable)
이터러블은 반복 가능한 객체로 내부적으로 이터레이터를 반환하는 [Symbol.iterator]()를 가진 값이다. 배열, 문자열, Map, Set 등이 기본적으로 이터러블입니다.
const arr = ['a', 'b', 'c'];
console.log(arr[Symbol.iterator]);
// [Function: values]
for (const word of arr) {
console.log(word);
}
// a
// b
// c
// 심볼이터레이터를 null로 없애버리면 에러 발생
arr[Symbol.iterator] = null;
for (const word of arr) {
console.log(word);
}
// TypeError: arr is not iterable
이터레이터(Iterator)
이터레이터는 next() 메서드를 가진 객체로, 이 메서드는 { value, done } 형태의 객체를 반환합니다.
const iter = arr[Symbol.iterator]();
console.log(iter);
// Object[Array Iterator] {}
console.log(iter.next()); // { value: 'a', done: false }
console.log(iter.next()); // { value: 'b', done: false }
console.log(iter.next()); // { value: 'c', done: false }
console.log(iter.next()); // { value: undefined, done: true }
console.log(iter.next()); // { value: undefined, done: true }
이터러블/이터레이터 프로토콜
이터러블을 for...of, 전개 연산자 등과 함께 동작하도록 한 규약입니다.
제너레이터
이터러블이자 이터레이터를 생성하는 함수
function* gen() {
yield 1;
yield 2;
yield 3;
}
let iter = gen();
console.log(iter.next()); // { value: 1, done: false }
console.log(iter.next()); // { value: 2, done: false }
console.log(iter.next()); // { value: 3, done: false }
console.log(iter.next()); // { value: undefined, done: true }
제네레이터는 [Symbol.iterator]를 가지고 있고
[Symbol.iterator] 실행 결과가 자기 자신을 리턴하는 well-formed 이터레이터이다.
console.log(iter[Symbol.iterator]() === iter); // true
지연 평가(Lazy Evaluation)와 이터러블
ES6의 이터러블/이터레이터 프로토콜의 도입으로 이터러블 중심 프로그래밍을 통해 지연 평가를 쉽게 구현할 수 있게 되었습니다.
이터러블로 지연평가가 가능한 map 메서드
const L = {};
L.map = function* (f, iter) {
for (const a of iter) yield f(a);
};
let it = L.map((a) => a + 10, [1, 2, 3]);
console.log(it.next()); // { value: 11, done: false }
기존 Array의 map과 다른 점은, Array.prototype.map은 모든 요소를 즉시 순회하며 새로운 배열을 생성하여 반환하지만, L.map은 실제 평가를 뒤로 미루고 next() 메서드가 호출될 때까지 기다립니다. 이는 필요한 시점에 필요한 값만 계산하는 지연 평가 방식으로, 특히 대용량 데이터 처리나 무한 시퀀스 다룰 때 메모리 효율성과 성능 면에서 큰 장점을 제공합니다.
지연 평가 filter
L.filter = function* (f, iter) {
for (const a of iter) {
if (f(a)) yield a;
}
};
const it2 = L.filter(a => a % 2, [1, 2, 3, 4]);
console.log(it2.next()); // { value: 1, done: false }
console.log(it2.next()); // { value: 3, done: false }
console.log(it2.next()); // { value: undefined, done: true }
지연 평가 take
const take = (limit, iter) => {
const result = [];
for (const a of iter) {
result.push(a);
if (result.length >= limit) return result;
}
return result;
};
// 무한 수열에서 처음 3개만 가져오기
function* infinity() {
let i = 0;
while (true) yield i++;
}
console.log(take(3, infinity())); // [0, 1, 2]
함수 조합을 통한 데이터 파이프라인 구축
지연 평가를 활용하면 여러 단계의 데이터 처리 파이프라인을 효율적으로 구축할 수 있습니다.
// 홀수만 필터링하고, 각 값을 두 배로 만든 후, 처음 3개만 가져오기
const result = take(3,
L.map(n => n * 2,
L.filter(n => n % 2, infinity())
)
);
console.log(result); // [2, 6, 10]
실제로 이 코드는 무한 시퀀스를 효율적으로 처리합니다. 필요한 3개의 값을 얻기 위해 최소한의 연산만 수행합니다.
이터러블/이터레이터와 함수형 프로그래밍의 결합 장점
- 선언적 프로그래밍 스타일: 코드의 의도가 명확히 드러납니다.
- 지연 평가: 필요한 시점에 필요한 값만 계산하여 효율성이 높아집니다.
- 무한 시퀀스 처리: 이론적으로 무한한 데이터 시퀀스도 효율적으로 다룰 수 있습니다.
- 메모리 효율성: 중간 결과를 모두 메모리에 저장하지 않아도 됩니다.
- 모듈성과 조합성: 작은 함수들을 조합하여 복잡한 로직을 구현할 수 있습니다.
참조
https://www.inflearn.com/course/functional-es6/dashboard
함수형 프로그래밍과 JavaScript ES6+ 강의 | MDU 유인동 - 인프런
MDU 유인동 | , 함수형 프로그래밍을 익히기 위한 최고의 강의!중급 자바스크립트 개발자로 성장하세요! [사진] 함수형 프로그래밍과 JavaScript ES6+ ES6+와 함수형 프로그래밍을 배울 수 있는 강의입
www.inflearn.com
[JS] 📚 이터러블 & 이터레이터 - 💯완벽 이해
이터러블(interable) 이터러블(interable)이란 자료를 반복할 수 있는 객체를 말하는 것이다. 우리가 흔히 쓰는 배열 역시 이터러블 객체이다. 그럼 만일 이 배열에게 이터러블 표식을 없애버리면 어
inpa.tistory.com
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Iterator
Iterator - JavaScript | MDN
An Iterator object is an object that conforms to the iterator protocol by providing a next() method that returns an iterator result object. All built-in iterators inherit from the Iterator class. The Iterator class provides a [Symbol.iterator]() method tha
developer.mozilla.org
'javascript' 카테고리의 다른 글
History api (pushState, replaceState) (0) | 2023.07.17 |
---|---|
forEach , map 알아보기 (0) | 2022.04.18 |
textContent , innerText 차이 (0) | 2022.04.09 |
i++와 i+=1의 차이점? (0) | 2022.04.05 |
HTMLCollection vs NodeList (0) | 2022.04.01 |