이터러블과 유사 배열 객체
iterable(반복 가능한) 객체란 for..of
문을 사용할 수 있는 객체를 의미합니다. 좀 더 정확히 표현하자면 이터러블이란 Symbol.iterator
메서드를 직접 구현하거나 프로토타입 체인을 통해 상속받은 객체를 말합니다.
대표적인 이터러블은 배열이 있습니다. 문자열 또한 이터러블입니다.
Symbol.iterator
이터러블 객체를 만들기 위해선 Symbol.iterator
메서드를 구현해야 합니다.
let range = {
from: 1,
to: 5,
};
range[Symbol.iterator] = function () {
return {
current: this.from,
last: this.to,
next() {
if (this.current <= this.last) {
return { done: false, value: this.current++ };
} else {
return { done: true };
}
},
};
};
for (let num of range) {
alert(num); // 1, 2, 3, 4, 5
}
동작 순서는 다음과 같습니다.
for..of
호출 시Symbol.iterator
가 호출된다.Symbol.iterator
는iterator
객체를 반환한다.- 이후
for..of
는 반환된iterator
객체만을 대상으로 동작하며 이때 다음 값도 정해진다. - 반복마다
next
메서드가 호출된다. done
프로퍼티가true
가 되면 반복문을 종료한다.
유사 배열 객체
유사 배열 객체란 index
와 length
프로퍼티를 가지고 있어 배열처럼 보이는 객체를 의미합니다.
let arrayLike = {
0: 'Hello',
1: 'World',
length: 2,
};
// 유사 배열 객체는 length 프로퍼티를 갖기 때문에 for 문으로 순회할 수 있습니다.
for (let i = 0; i < arrayLike.length; i++) {
console.log(arrayLike[i]); // Hello World
// 유사 배열 객체는 배열처럼 index를 통해 객체에 접근할 수 있습니다.
}
// 유사 배열 객체는 이터러블이 아니기 때문에 for..of 순회 불가
for (const key of arrayLike) {
console.lang(key); // TypeError: Invalid attempt to iterate non-iterable instance.
}
for..in 문과 for..of 문의 차이
for..in
문은 객체의 프로토타입 체인 상에 존재하는 모든 프로퍼티 중에서 프로퍼티 어트리뷰트 [[Enumerable]]
값이 true
인 프로퍼티를 열거합니다.
단, 키가 Symbol인 프로퍼티는 열거하지 않습니다.
for..of
문은 내부적으로 next()
메서드를 호출하여 순회하며 객체의 value 값을 할당하여 done
프로퍼티가 true
가 될 때까지 순회합니다.
Array.from()
Array.from()
메서드를 이용하여 유사 배열 객체 또는 이터러블을 배열로 변환할 수 있습니다.
let arrayLike = {
0: 1,
1: 2,
length: 2,
};
const arr = Array.from(arrayLike);
arr.push(3);
console.log(arr); // [1, 2, 3]
참조
- 모던 자바스크립트 Deep Dive
- https://ko.javascript.info/iterable