이터러블과 유사 배열 객체
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