Til-3 -일급함수, 이터러블/이터레이터
2021.06.30
평가
- 코드가 계산(Evaluation) 되어 값을 만드는 것
일급함수: 함수가 값으로 다뤄질 수 있다
- 값으로 다룰 수 있다
- 변수에 담을 수 있다
- 함수의 인자로 사용가능
- 함수의 결과로 사용가능
const a=10; const add10 = a=> a+10 const r =add10(10); console.log(r); //일급함수 이기에 아래와 같이 사용가능 var f1= ()=>()=>1; console.log(f1()); //()=>1 f1()(); //1 (f1()); //()=>1
고차함수: 함수를 값으로 다루는 함수
a. 함수를 인자로 받아서 실행하는 함수
const apply1 = f => f(1);
const add2 = a => a + 2;
log(apply1(add2));
log(apply1(a => a - 1));
const times = (f, n) => {
let i = -1;
while (++i < n) f(i);
};
times(log, 3);
times(a => log(a + 10), 3);
b. 함수를 만들어 리턴하는 함수
const addMaker = a => b => a + b;
const add10 = addMaker(10);
log(add10(5));
log(add10(10));
- es6에서의 리스트 순회(for of , for in)
const list = [1, 2, 3];
for (var i = 0; i < list.length; i++) {
// log(list[i]);
}
const str = 'abc';
for (var i = 0; i < str.length; i++) {
// log(str[i]);
}
for (const a of list) {
// log(a);
}
for (const a of str) {
// log(a);
}
-
이터러블/이터레이터 프로토콜
a. 이터러블: 이터레이터를 리턴하는 Symbol.iterator 를 가진 값 b. 이터레이터: { value, done } 객체를 리턴하는 next() 를 가진 값 c. 이터러블/이터레이터 프로토콜: 이터러블을 for...of, 전개 연산자 등과 함께 동작하도록한 규약
### Array를 통해 알아보기
<script>
log('Arr -----------');
const arr= [1, 2, 3];
let iter1=arr[Symbol.iterator](); //arr: 이터러블, iter1: 이터레이터
for (const a of iter1)log(a); //iter1.next(); 입력할때마다 다음값 출력
</script>
### Set을 통해 알아보기
<script>
log('Set -----------');
const set= new Set([1, 2, 3]);
for (const a of set)log(a);
</script>
### Map을 통해 알아보기
<script>
log('Map -----------');
const map= new Map([['a', 1], ['b', 2], ['c', 3]]);
for (const a of map.keys())log(a); //키 정보만 가져옴
for (const a of map.values())log(a);
for (const a of map.entries())log(a);
console.clear();
</script>
- 사용자 정의 이터러블/이터레이터 구현
const iterable = {
[Symbol.iterator]() { **//동적인 값을 key로 사용하기 위한 메소드 생성방법(이해X)**
let i = 3;
return {
next(){
return i==0? {done:true}: {value:i--, done:false}
},
**[Symbol.iterator](){return this}**
//이걸로 인해 iterator for of 문이 가능하고 next 후 중간부터도 시작 가능함
}
}
}
var iterator= iterable[Symbol.iterator](); //메소드 실행
console.log(iterator.next()); //{ value: 3, done: false }
console.1log(iterator.next()); //{ value: 2, done: false }
console.log(iterator.next()); //{ value: 1, done: false }
for(a of iterable){
console.log(a); //3,2,1
}
for(a of iterator){ // [Symbol.iterator](){return this} 때문에 실행 가능
console.log(a); //3,2,1
}
//기존 iterable은 next를 사용해서 중간부터 시작할 수 있음
const arr2= [1,2,3];
let iter2= arr2[Symbol.iterator]();
iter2.next(); //한번 호출 했음으로 2,3 출력
for(a of iter2){
console.log(a);
}
- 최근 array, map, set 내장 객체 뿐만 아니라 오픈 소스및 브라우저 web api 에서도 이터러블/이터레이터를 사용 할 수 있음
for(a of document.querySelectorAll('*')){
console.log(a)
};
- 전개연산자 역시 이터러블/이터레이터를 이용한 함수
console.clear();
const a = [1, 2];
// a[Symbol.iterator] = null; //주석풀면 전개연산자 사용 불가
log([...a, ...arr, ...set, ...map.keys()]);
-
제너레이터와 이터레이터
- 제너레이터: well-formed 이터레이터를 리턴하는 함수
- 자바스크립트에서 iterator이면 for of 로 순회 할 수 있다
- 즉 제너레이터 함수 내부 문장을 사용하여 어느 값이나 상태를 순회 할 수 있다
function *gen(){ yield 1; yield 2; yield 3; return 100; } let iter =gen(); console.log(iter == iter[Symbol.iterator]()); //well-formed이터레이터 console.log(iter.next()); console.log(iter.next()); console.log(iter.next()); console.log(iter.next()); //{ value: 1, done: false } //{ value: 2, done: false } //{ value: 3, done: false } **//{ value: 100, done: true }** for(let a of gen()) console.log(a); //1,2,3 (리턴값은 안나옴)
-
제너레이터 실습
function *odd(l){
for(let i=0;i<l;i++){
if(i%2) yield i;
}
}
let iter = odd(10);
for(a of iter){
console.log(a);
}
//무한히 실행되도 next로 평가받는 시점까지의 수만 나옴
function *infinity(i=0){
while(true) yield i++
}
let iter2= infinity();
console.log(iter2.next());
console.log(iter2.next());
console.log(iter2.next());
//
function *limit(l, iter){
for(const a of iter) {
yield a; //next() 할때마다 값이 나옴
if (a == l) return;
}
}
let iter4= limit(4,[1,2,3,4,5,6]); //까지만 출력
for(let a of iter4){
console.log(a);
}
//limit와 infinity를 이용해 아래와 같이 변경 가능
function *odd(l){
**for(const i of limit(l,infinity(1))) {**
if (i % 2) yield i;
if(i==l) return;
}
}
- for...of, 전개 연산자, 구조 분해, 나머지 연산자
- 이터레이터 활용
console.log(...odd(10)); //1~9
console.log([...odd(10), ...odd(20)]); //[1~9, 1~19]
const [head , ...tail] = odd(5);
console.log(head); //1
console.log(tail); //[3,5]
댓글을 작성해보세요.