맨 땅에 프론트엔드 개발자 되기

Object is not iterable / 객체 순회 for in, Object.keys, value, entries - 에러 기록 본문

코딩 공부 일지/JavaScript

Object is not iterable / 객체 순회 for in, Object.keys, value, entries - 에러 기록

헬로코딩 2022. 3. 3. 21:30
728x90

오늘은 firebase realtime database를 사용하다가 겪은 에러에 대해 기록해보려고 한다.

참고로, 아래 내용은 리액트의 환경이다.

 

1. 에러 내용

 

firebase realtime database를 이용해서 todo list 앱의 데이터를 저장했다. 저장된 데이터는 다시 불러와 화면에 뿌려줘야 했는데, 여기서 받은 데이터는 key와 내용이 있는 객체로 반환되었다. (key는 데이터의 ID, value는 데이터 였다.) 객체를 불러와 map을 이용하여 자식 컴포넌트에 내용을 뿌려주려고 하니 에러가 났다. 에러의 내용은 map을 이용할 수 없다는 내용이었고, 대충 Object is not iterable 이라는 내용이었다. 

 

 

그렇다. 객체는 iterable Object가 아니다. 그래서 map, filter와 같이 iterable Object에 쓸 수 있는 메소드를 쓸 수 없다.

(대표적인 iterable Object에는 배열, 문자열 등이 있다. 배열도 사실상 key 값이 있기 때문에 객체이지만, 여기서 말하는 객체는 별도의 key값이 존재하는 객체로 한정한다.)

 

2. 왜 객체는 iterable Object가 아닐까?

 

내 첫 의문은 '왜 객체는 iterable Object가 아닐까?' 하는 의문이었다. 왜냐하면 콘솔창에 보이는 데이터는 key가 0,1,2 가 아닐 뿐이지 배열처럼 보였기 때문이다. 

 

 

너무나도 자연스럽게 map을 사용할 수 있을 것 같았지만, 폭풍 구글링 결과 가장 이해할만한 답을 찾았다. 사실, 모든 Object가 복수의 값을 가지고 있는 것은 아니다. 기본적으로 Object는 key와 value를 가진 data다. 그러므로, Object가 iterable 하다는 것은 부자연스럽다. Object가 여러 개인 데이터의 집합이 있을 수 있지만, Object는 그 자체로 단일 정보이기 때문이다. 

 

3. 그래서 객체에 접근하는 다른 방법이 존재한다.

 

* for in

ES6에서 가능한 문법으로, for of 와 비슷해서 헷갈릴 수 있지만, for of 는 배열에서 사용하고, for in 은 객체에서 사용한다.

 

const obj = {
	name: "Sophia",
	age: "50",
	gender: "female"
}

for (let key in obj) {
	console.log("key : " + key);
	console.log("value : " + obj[key]);
}

 

* 객체 전용 메소드 Object.keys(), value(), entries()

Object 는 javascript에 내장되어 있는 window나 document와 같은 존재다. 

 

- Object.keys()

객체의 키만을 담은 배열을 반환한다.

 

const obj = {
    name: "Sophia",
    age: "50",
    gender: "female"
  }

  console.log(Object.keys(obj));

 

- Object.values()

객체의 값만을 담은 배열을 반환한다.

 

const obj = {
    name: "Sophia",
    age: "50",
    gender: "female"
  }

  console.log(Object.values(obj));

 

- Object.entries()

객체의 [키, 값] 쌍을 담은 배열을 반환한다.

 

const obj = {
    name: "Sophia",
    age: "50",
    gender: "female"
  }

  console.log(Object.entries(obj));

 

- Object.fromEntries()

만약 객체를 배열로 만들고 반복문을 통해 어떤 작업을 수행한 뒤 다시 객체로 돌리고 싶을 때는 다음과 같이 활용할 수 있다.

 

const salaries = {
    "Sophia": 100,
    "John": 200,
    "Mary": 300
  }

  const newObj = Object.entries(salaries).map(([key,value]) => [key, value * 2]);
  console.log(Object.fromEntries(newObj));

728x90