TIL/JS

조금 어려운 for ... of, for ... in, 유사 배열 객체

saramnim 2023. 3. 21. 20:26
728x90
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 - 자바스크립트의 기본 개념 책을 읽고 정리했습니다.
더 자세한 내용은 책을 구매해보시길 권장드립니다!
728x90
반응형