Javascript에서의 Interface, iterator 객체의 개념에 대해서 살펴보자. 😊
An 'interface' is a set of property keys whose associated values match a specific specification. Any object that provides all the properties as described by an interface's specification conforms to that interface. An interface is not represented by a distinct object. There may be many separately implemented objects that conform to any interface. An individual object may conform to multiple interfaces.
🗒스펙문서 (https://tc39.es/ecma262/#sec-iteration)
예를 들어, Test Interface 정의를 test라는 키를 갖고, 값으로 문자열을 받아 Boolean을 리턴하는 함수가 온다고 하자.
{
test(str){return true;}
}
그럼 다음과 같이 간단한 Test Interface의 정의를 만족하는 객체를 만들 수 있을 것이다.
{
next() {
return {value: 1, done: true};
}
}
{
[Symbol.iterator](){
return {
next() {
return {value: 1, done: true};
}
}
}
}
다음과 같은 예를 만들 수도 있음.
const iter = {
[Symbol.iterator]() {
return this;
},
arr: [1, 2, 3, 4, 5],
next() {
return {
done: this.arr.length === 0,
value: this.arr.pop()
};
}
};
for (const item of iter) {
console.log(item);
}
/*
출력
5
4
3
2
1
*/
const iter = {
[Symbol.iterator]() {
return this;
},
arr: [1, 2, 3, 4, 5],
next() {
return {
done: this.arr.length === 0,
value: this.arr.pop()
};
}
};
const [a, ...b] = iter;
console.log(a);
/*
출력
5
*/
iterable interface의 정의를 충족 시키면 다음과 같이 array destructuring같은 언어 스펙을 사용할 수 있다.
// 문자열도 iterable이다.
const str = '문자열입니다.';
const iterator = str[Symbol.iterator]();
while(true) {
const iteratorResultObject = iterator.next();
if (iteratorResultObject.done) break;
console.log(iteratorResultObject.value);
}
비슷해 보이지만 아주 다른 용어 두 가지가 있다. 헷갈리지 않으려면 두 용어를 잘 이해하고 있어야 한다.
범용 메서드 Array.from는 이터러블이나 유사 배열을 받아 진짜
Array를 만들어준다. 이 과정을 거치면 이터러블이나 유사 배열에 배열 메서드를 사용할 수 있다.
// 유사 배열
const arrayLike = {
0: 1,
1: 2,
length: 2
};
console.log(Array.from(arrayLike).pop());
// iterable
const iter = {
[Symbol.iterator]() {
return this;
},
arr: [1, 2, 3, 4, 5],
next() {
return {
done: this.arr.length === 0,
value: this.arr.pop()
};
}
};
/*
pop을 하면서 반복하는 iterable 객체이므로
Array.from(iter)
= [5,4,3,2,1]
*/
console.log(Array.from(iter).pop());
// 출력
// 2
// 1