개발여행의 블로그

[JavaScript] 왜 Object(객체)는 Iterable object가 아닌것일까? (iterable과 iterator에 대해 알아보자!) 본문

개발/javaScript

[JavaScript] 왜 Object(객체)는 Iterable object가 아닌것일까? (iterable과 iterator에 대해 알아보자!)

개발 여행 2021. 11. 26. 19:59
728x90

콘솔에 이것저것 작성하면서 놀고(?) 있을 때 문득 Object는 왜 iterable 하지 않은지 의문이 생겨서 폭풍 서치를 시작했다.

(맞지 않은 내용이 있다면 댓글 부탁드립니다. 미리 감사합니다!)

 

Iterable이란?

iteration protocol을 따르는 객체를 iterable이라고 한다. 쉽게 말하면 iterable은 배열을 일반화한 object인 것이다.

'반복 가능한'이라는 의미의 iterable을 풀어서 생각해보면, 반복 가능한 객체가 iterable object가 되는 것이다.

예를 들어, 배열, 문자열 등이 iterable이다.


그럼 여기서 Iteration protocol 은 무엇인가?

먼저 protocol에 대해 정리해보자!

컴퓨터와 컴퓨터 혹은 컴퓨터와 다른 장비 사이에서 데이터 통신을 원활하게 하기 위해 필요한 통신 규약이다.

즉, 송신자와 수신자가 서로 약속을 해두고 약속된 규칙에 맞춰 통신을 할 수 있는 것이다.

(예를 들어 신호 송신 순서, 데이터 표현법, 오류 검출법 등을 정할 수 있다.)

 

더 쉬운 예로는 우리가 사용하는 언어가 있다.

한글이라는 언어 체계에 맞춰 대화를 하기 때문에 나의 옆사람과 원활하게 의사소통할 수 있는 것이다.

만약 내가 포루투갈어를 구사하고, 나의 옆사람은 한국어를 구사한다면? 의사소통이 불가능할 것이다.

 

Iteration protocol은 객체가 특정 조건을 충족한다면 어떤 객체든 iterable or iterator로 평가될 수 있는 약속인 것이다.


Iterable? Iterator?

iterable과 iterator는 도대체 무엇이길래?라는 생각이 들것이다.

아래에서 iterable과 iterator의 protocol에 대해 알아보자!

 

The Iterable Protocol?

iterable protocol은 JavaScript 객체가 반복 가능한 작업을 할 수 있도록 정의하거나 customize 하는 것을 허용한다.

예를 들어 for..of 구조에서 value를 반복하는 동작을 수행할 수 있는 것이다.

Array와 Map 등의 built-in type들은 default iteration이 built-in-iterables이다.(iterable 하다는 것이다.)

 

iterable 하기 위해서는 아래와 같은 약속을 따라야 한다.

 - 객체는 object @@iterator 메서드를 구현해야 한다.

   객체는 Symbol.iterator를 통해 사용할 수 있는 @@iterator 속성을 가져야 한다는 것을 의미한다.

출처 - MDN

정리하자면,

The iterable protocol은 객체가 iterable하기 위해 따라야 하는 규약이고,

iterable"반복 가능한 객체"가 되는 것이다.


The Iterator Protocol?

iterator protocol은 값의 시퀀스를 생성하는 표준 방법과, 값이 생성되었을 때 잠재적인 반환 값을 정의한 규약이다.

 

아래의 조건을 만족하면 iterator이다.

1) 객체가 next() 메서드를 가지고 있어야 한다.

2) next() 메서드는 2가지 property를 가진 객체를 반환해야 한다.

 

-> 2가지 property

 - done(boolean)

: iterator가 마지막 반복 작업을 마쳤을 경우 true / 작업이 남았을 경우 false 리턴

 

- value(any)

: iterator로부터 반환되는 모든 자바스크립트 값이다. done이 true일 경우 생략 가능하다.

 

정리

The iterator protocol은 iterator가 되기 위해 따라야하는 규약이고,

iterator"next 메서드를 사용해 객체를 순환할 수 있는 객체"이다.

 


그 외 Iteration protocols의 사용 예시나 Iterable의 예시 등은 다음 포스팅에서 다뤄보고자 한다.

왜냐면 주제의 메인이 아닌 글이 길어질 것 같기 때문이다.


 

여기까지 iterable에 대해 알아보았다!

그럼 왜 객체는 iterable이 아닌걸까?

(이 결론은 100% 저의 주관입니다.)

 

결론부터 말하자면,

모든 객체는 collection이 아니기 때문에 객체가 defalut 하게 iterable 하다면 제너럴 하지 않을 것 같다는 생각이 들었다.

null의 type도 object인데 이것이 iterable 하다면 조금 이상하지 않은가..?

 

이 결론을 세우기 전에 메모리 효율성 때문인가?라는 생각도 했다.

Array, Set, Map 등은 모두 다음 값이 무엇인지 정보를 가지고 있는데 Object의 경우 다음 값이 무엇인지 정보를 가지고 있지 않기 때문에 iterable하지 않겠다는 생각을 했다.

 

자바스크립트에서 참조하지 않은 값은 가비지 컬렉터가 수거하므로

만약 해당 object를 사용하는 곳이 없다면 바로 가비지 컬렉터에 의해 수거당할 수 있을 것이다.

 

반면, Map이나 Set 같은 경우 next value의 정보를 가지고 있기 때문에 next value가 아무 곳에서 쓰이지 않는다고 해도

이전 value가 참조를 해서 가리키고 있기 때문에 가비지 컬렉터에 수거당하기 어려울 것이다.

 

이런 생각을 가지고 질문을 했었는데,

아마 단순히 제너럴 한 이유로 object를 iterable하지 않게 구현했을 것이라고 말씀해주셨다.

원점으로 돌아와 생각해보니 object가 iterable 하다면 합리적이지 않을 것 같다.

 

만약 object를 iterable 하게 사용하고 싶다면 Symbol.iterator 속성을 정의하여 사용할 수 있으므로

아래의 예시와 같이 사용자 정의에 의해 옵셔널 하게 사용하는 것이 적절할 것 같다는 생각이다.

var myIterable = {};
myIterable[Symbol.iterator] = function* () {
    yield 1;
    yield 2;
    yield 3;
};
[...myIterable]; // [1, 2, 3]

 

 

 

 

 

 

 

참고

https://stackoverflow.com/questions/29886552/why-are-objects-not-iterable-in-javascript

 

Why are Objects not Iterable in JavaScript?

Why are objects not iterable by default? I see questions all the time related to iterating objects, the common solution being to iterate over an object's properties and accessing the values within...

stackoverflow.com

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Iteration_protocols

 

Iteration protocols - JavaScript | MDN

ECMAScript 2015 (ES6)에는 새로운 문법이나 built-in 뿐만이 아니라, protocols(표현법들)도 추가되었습니다. 이 protocol 은 일정 규칙만 충족한다면 어떠한 객체에 의해서도 구현될 수 있습니다.

developer.mozilla.org

728x90
Comments