함수형 프로그래밍과 JavaScript ES6+ 강의를 듣고 정리한 내용입니다.
✅ 리스트 순회
기존 ES5 문법에서의 리스트 순회는 for문을 이용했다.
const arr = [1, 2, 3];
for(var i = 0; i < arr.length; i++){
console.log(arr[i]);
}
// output
// 1
// 2
// 3
const str = "abc";
for(var i = 0; i < str.length; i++){
console.log(str[i]);
}
// output
// a
// b
// c
i의 값을 증가시키면서 대상의 i번째 요소에 접근하는 것이다.
ES6+에서는 for...of문이 추가되었다.
const arr = [1, 2, 3];
for(const a of arr){
console.log(a);
}
// output
// 1
// 2
// 3
const str = "abc";
for(const a of str){
console.log(a);
}
// output
// a
// b
// c
for...of문 문법이 추가됨으로써 대상을 순회하기가 더욱 간편해졌다.
✅ for of문의 원리
for...of문의 원리를 알기 전 js에는 array, set, map이라는 내장 객체가 있다.
이 내장 객체들은 모두 for...of문으로 내부 순회가 가능하다.
이중 array는 위의 인덱스로 접근하는 것처럼 arr[1], arr[2] 등으로 값을 확인할 수 있지만 set, map은 set[1], map[2] 등으로 값에 접근하려고 하면 undifined가 뜨면서 접근이 불가능하다.
그런데 for...of문은 어떻게 set, map의 내부를 순회할 수 있을까?
답은 array, set, map이 이터러블/이터레이터 프로토콜을 따르고 있기 때문이다.
여기서 이터러블이란 iterator를 리턴하는 [Symbol.iterator]()를 가진 값으로 array, set, map을 이터러블이라 할 수 있다.
이터레이터는 {value, done} 객체를 리턴하는 next()를 가진 값이다.
이터러블/이터레이터 프로토콜은 이터러블을 for...of, 전개연산자등과 함께 동작하도록 한 규약이다.
const arr = [1, 2, 3];
let iterator = arr[Symbol.iterator]();
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
// output
// { value: 1, done: false }
// { value: 2, done: false }
// { value: 3, done: false }
// { value: undefined, done: true }
arr은 iterator를 리턴하는 [Symbol.iterator]메소드를 가지고 있고 이를 iterator라는 변수에 담아 next 메소드를 사용함으로써 내부를 순회하고 있다.
내부를 순회할 때는 done이 false였다가 내부 순회가 끝나자 done이 true로 바뀌는 것을 확인할 수 있다.
즉, for...of문은 이터러블/이터레이터 프로토콜에 따라 iterator를 이용해 내부를 순회하며 done이 false면 value를 출력하고 true이면 순회를 끝내는 작업을 하고있는 것으로 볼 수 있다.
✅ 사용자 정의 이터러블
이터러블은 이터레이터를 리턴하는 [Symbol.iterator]()를 가진 값이라고 했다.
따라서 이터러블을 만들기 위해서는 다음과 같은 규칙이 필요하다.
- [Symbol.iterator]()를 가지고 있을 것.
- next()를 통해 내부에 접근할 것.
- 내부 순회가 끝나면 done = true, 끝나기 전이면 {value, done: false} 객체를 리턴할 것.
- iterator의 iterator는 자기 자신을 반환할 것.
const iterable = {
[Symbol.iterator](){
let i = 3;
return{
next(){
return i == 0 ?
{done: true}
: {value: i--, done: false}
},
[Symbol.iterator](){
return this;
}
}
}
}
let iterator = iterable[Symbol.iterator]();
for(const a of iterable){
console.log(a);
}
// output
// 3
// 2
// 1
for(const a of iterator){
console.log(a);
}
// output
// 3
// 2
// 1
✅ 전개연산자
전개연산자도 이터러블/이터레이터 프로토콜을 따른다.
그렇기 때문에 다음과 같은 결과를 얻을 수 있다.
const a = [1, 2];
console.log([...a, ...[3, 4]])
// output
// [1, 2, 3, 4]
'JavaScript' 카테고리의 다른 글
[FP&ES6+] map, filter, reduce (0) | 2021.12.01 |
---|---|
[FP&ES6+] 제너레이터 (0) | 2021.12.01 |
[FP&ES6+] 평가와 일급, 일급함수와 고차함수 (0) | 2021.09.27 |
ES6 문법 정리 (0) | 2021.07.24 |
검색화면만들기(MVC) - 추천 검색어 탭 구현 (0) | 2021.07.02 |
댓글