조금 어려운 for ... of, for ... in, 유사 배열 객체
for ... of, for ... in, 유사 배열 객체, 이터러블에 대해 알아보자!
for ... of 문 vs for ... in 문
for ... of 문
이터러블을 순회하면서 이터러블의 요소를 변수에 할당
for (변수선언문 of 이터러블) { ... }
- 내부적으로 이터레이터의 next 메서드를 호출해 이터러블 순회
- next 메서드가 반환한 이터레이터 리절트 객체의 value 프로퍼티 값을 for ... of 문의 변수에 할당
- 이터레이터 리절트 객체의 done 프로퍼티 값이 false면 이터러블의 순회를 계속하고 true면 이터러블의 순회 중단
for (const item of [1, 2, 3]){
console.log(item); // 1 2 3
}
for ... in 문
for (변수선언문 in 객체) { ... }
- 객체의 프로토타입 체인 상에 존재하는 모든 프로토타입의 프로퍼티 중 프로퍼티 어트리뷰트 [[Enumerable]]의 값이 true인 프로퍼티를 순회하며 열거
- 프로퍼티 키가 심벌인 프로퍼티는 열거하지 않는다.
유사 배열 객체
인덱스로 프로퍼티 값에 접근 가능 및 length 프로퍼티를 갖는 객체
=> length 프로퍼티를 갖기 때문에 for 문 순회 가능
=> 인덱스를 나타내는 숫자 형식의 문자열을 프로퍼티 키로 가지므로 마치 배열처럼 인덱스로 프로퍼티 값에 접근 가능
- 유사 배열 객체는 이터러블이 아닌 일반 객체이므로 Symbol.iterator 메서드가 없기 때문에 for ... of 문으로 순회 불가능
- arguments, NodeList, HTMLCollection은 유사 배열 객체이면서 이터러블
- Array.from 메서드는 유사 배열 객체 또는 이터러블을 인수로 받아 배열로 변환 후 반환
const arrLike = {
0: 1,
1: 2,
2: 3,
length: 3
}
for (let i = 0; i < arrLike.length; i++) {
console.log(arrLike[i]); // 1 2 3
}
for (const item of arrLike) {
console.log(item);
} // TypeError
const arr = Array.from(arrLike);
console.log(arr); // [1, 2, 3]
이터레이션 프로토콜이 중요한 이유?
ES6 이전
순회 가능한 데이터 컬렉션(배열, 문자열, 유사 배열 객체, DOM 컬렉션 등)은 통일된 규약 없이 각자 구조를 가지고 for문, for ... in 문, forEach 메서드 등 다양한 방법으로 순회
ES6 이후
순회가능한 데이터 컬렉션을 이터레이션 프로토콜을 준수하는 이터러블로 통일해 for ... of 문, 스프레드 문법, 배열 디스트럭처렁 할당의 대상으로 사용할 수 있도록 일원화
데이터 공급자: 이터러블
=> 다양한 데이터 공급자가 이터레이션 프로토콜을 준수하도록 규정
데이터 소비자: for ... of 문, 스프레드 문법, 배열 디스트럭처링 할당
=> 이터레이션 프로토콜만 지원하도록 구현
=> 내부에서 Symbol.iterator 메서드를 호출해 이터레이터를 생성하고 이터레이터의 next 메서드를 호출하여 이터러블을 순회하며 이터레이터 리절트 객체 반환
=> 이터레이터 리절트 객체의 value/done 프로퍼티 값을 취득
이터레이션 프로토콜은 다양한 데이터 공급자가 하나의 순회 방식을 갖도록 규정한다.
-> 데이터 소비자가 효율적으로 다양한 데이터 공급자를 사용할 수 있도록 데이터 소비자와 데이터 공급자를 연결하는 인터페이스의 역할
본 게시글은 모던자바스크립트 Deep Dive - 자바스크립트의 기본 개념 책을 읽고 정리했습니다.
더 자세한 내용은 책을 구매해보시길 권장드립니다!