자바스크립트를 사용하다 보면 자연스럽게 [... arr]처럼 스프레드 연산자를 사용한다.
그게 왜 가능 할까? 한번 알아보자.
이터레이션 프로토콜(Iteration Protocol)
이터레이션 프로토콜이란?
반복, 순회를 하기 위해서 따르는 규격, 약속, 인터페이스이다.
이 프로토콜을 따르면 for of나 spread 연산자를 사용 가능 하다.
자바스크립트에서는 Array, String, Map, Set이 녀석들이 이 프로토콜을 따른다.
그럼 이 이터레이션을 따르는 것은 뭘까?
그건 Iterable, Iterator 프로토콜을 따르면 된다. 간단하다.
아래 두 가지만 기억하면 된다.
Iterable: Iterator을 리턴하는 [Sysmbol.iterator]()을 가진 값
Iterator: next() 함수를 가진 객체를 리턴하는데 next라는 함수에는 {value, done}를 리턴하면 된다.
그러면 Array에 [Sysmbol.iterator]()이 있는지 확인해 보자
확인을 해보면 정말 들어있다. 그러면 Iterator(next() 함수를 가진 객체를 리턴하는 객체)도 있는지 확인해 보면
next 프로퍼티가 있는지 확인하면 true가 출력되고
next()를 호출하면 첫 번째 값인 3이 나오는 걸 볼 수 있음
이제 직접 [3,2,1]을 만들어보자
다시 이터레이션 프로토콜을 살펴보면 반복, 순회를 위한 규약, 인터페이스이다. 그럼 이 인터페이스를 따르려면
iterable와 iterator 프로토콜을 따라야 한다.
iterable은 Iterator을 리턴하는 Sysmbol.iterator을 가진 값이고 iterator은 next() 함수를 가진 객체를 리턴하는데 next라는 함수에는 {value, done}를 리턴하면 된다.이다.
아래 코드를 보면 testIterable라는 객체는 Symbol.iterator라는 함수를 가지는 데 이 함수는 next()라는 함수를 포함한 객체를 리턴하고 있어서 이터레이션 프로토콜을 따르고 있다.
const testIterable = {
[Symbol.iterator]() {
let i = 3;
return {
next() {
return i === 0 ? { done: true } : { value: i--, done: false };
},
};
},
};
위에 작성한 코드 결과도 for of와 스프레드 연산자가 잘 작동되고 있다.
그러면 이제 저 next()라는 애는 뭘까?
next는 그냥 호출하면 현재 값과 더 이상 순회할 게 있는지 없는지를 알려주는 애이다.
여기서 잘 만들어진 이터레이터는 next를 호출하다 for of나 스프레드 연산자를 사용하면 next 다음 값들부터 순회를 하도록 되어있다. 이것을 구현하려면
아래처럼 [Symbol.iterator]의 리턴 값을 this로 해주면 된다. 그러면
const testIterable = {
[Symbol.iterator]() {
let i = 3;
return {
next() {
return i === 0 ? { done: true } : { value: i--, done: false };
},
[Symbol.iterator]() {
return this;
},
};
},
};
next로 3이 출력되고 나머지 2, 1이 스프레드 연산자로 출력되는 것을 확인할 수 있다.
지금까지 당연하게 쓴 for of, spread가 어떻게 돌아가는지 확인했다. 쉽지 않다.
'언어 > 자바스크립트' 카테고리의 다른 글
클로저(Closures) (1) | 2024.02.21 |
---|---|
실행 컨텍스트(렉시컬 스코프, 렉시컬 환경, 스코프 체인, 호이스팅) 이 글로 끝내버리기 (0) | 2023.05.13 |
BigInt 큰 숫자 다루기 (0) | 2023.04.12 |
자바스크립트 This 이걸로 끝내기 (0) | 2023.03.28 |
이벤트 캡처링과 버블링 (0) | 2023.03.06 |