JavaScript | for in 문을 제대로 알아보자! ( + for of 반복문)

앙두·2023년 5월 25일
0

JavaScript

목록 보기
18/21

🔄 for in 반복문

for in 반복문 예시

const obj = {
  name: 'Ellie',
  age: '20',
  favorite: 'sushi',
}

for (el in obj) {
	console.log(el)
  // 'name', 'age', 'favorite'
}

1️⃣ for in 문 특징 1

for in 반복문은 대체로 객체에서 사용합니다.
enumerable(열거 가능한, 셀 수 있는) 한 프로퍼티만 임의의 순서로 반복하기 때문입니다.

우리가 객체를 생성할 때, 우리가 직접 작성하는 key와 value값만 저장되는 것이 아닙니다.
그 외에 숨겨진 속성 3개가 같이 저장됩니다.
그 속성은 아래와 같이 확인해볼 수 있습니다.

Object.getOwnPropertyDescriptor(객체명, '프로퍼티 key 이름')

console.log(Object.getOwnPropertyDescriptor(obj, 'name')

출력값 👇🏻

{
  value: 'water',
  writable: true,
  enumerable: true,
  configurable: true
}

위와 같이 for in 문은, enumerabletrue 인 프로퍼티만 반복하는 것입니다.

🤷🏻‍♀️ 그럼 배열에는 아예 사용하면 안되나요?

배열에 아예 사용이 안되는 것은 아닙니다.

예시 👇🏻

const array = [10, 9, 34, 234, 1];

for (let el in array) {
  console.log(el, array[el]);
} // '0', '1', '2', '3', '4'

위와 같이, index 로 출력되는 것을 볼 수 있습니다.
자바스크립트는 배열을 object 로 인식하기 때문에 그렇습니다.
그러나 for in문은 열거가능한 프로퍼티값을 임의로 반복합니다.
배열의 요소들은 프로퍼티가 아닌 값이기 때문에, index 가 출력이 되는 것입니다.

❗️for in 문을 배열에는 사용하지 않는 것을 권장하는 이유는!
배열은 index가 중요한데, for in 문은 index와 상관없이 임의의 순서로 반복을 하는 특성을 가지고 있기 때문입니다.
꼭 잘 출력되는 것처럼 보여도 for in문 특성상 순서대로 반복해준다는 보장이 없기때문에 위험합니다.

2️⃣ for in 문 특징 2

for in문은 객체의 prototype까지도 반복문으로 출력시킵니다.

let picnicPlan = ['park', 'hat', 'watermelon', 'jiwon'];

class Picnic {
  constructor(place, supplies, fruit, friend) {
    (this.place = place),
      (this.supplies = supplies),
      (this.fruit = fruit),
      (this.friend = friend);
  }
}

Picnic.prototype.data = '2023년 6월 24일';
let event = new Picnic(...picnicPlan);
for (key in event) {
  console.log(`key: ${key} / value: ${event[key]}`);
}

출력값 👇🏻

'key: place / value: park'
'key: supplies / value: hat'
'key: fruit / value: watermelon'
'key: friend / value: jiwon'
'key: date / value: 2023년 6월 24일'

prototype에 추가한 값 까지 출력해주는 것을 확인할 수 있습니다.

그러나 대부분의 경우 prototype의 값은 필요하지 않기 때문에,
이를 해결하기 위해 if문과 hasOwnProperty() 함수를 사용해줘야 합니다.

hasOwnProperty()의 기능은,
해당 객체가 ()안에 들어갈 키값을 가지고 있는지 없는지를 판단하여, true / false 를 반환합니다.
아래 코드로 한번 사용해봅시다.

for (key in event) {
  if (event.hasOwnProperty(key)) {
    console.log(`key: ${key} / value: ${event[key]}`);
  }
}

출력값 👇

'key: place / value: park'
'key: supplies / value: hat'
'key: fruit / value: watermelon'
'key: friend / value: jiwon'

if문과 hasOwnProperty()함수를 사용해주면,
prototype을 제외한 해당 객체가 가지고 있는 key 와 value 값만 확인할 수 있습니다.

prototype까지 다 반복하여 출력해주는 for in문의 이 특징은,
바로 "디버깅"할 때 유용하다고 합니다.
눈에 보이지 않는 것들까지 다 순환해주기 때문이죠!

근데,
저와 같이 눈에 보이는 것들도 잘 사용해먹지 못하는 코린이들에게는 당장 쓸 일은 없을 것 같습니다! 🥰



🔄 for of 반복문

for in 반복문은 객체에, for of 반복문은 배열에!

let fruitArr = ['apple', 'grape', 'mango', 'orange'];

for (el of fruitArr) {
  console.log(el);
}

출력값 👇

'apple'
'grape'
'mango'
'orange'

for in 문과 유사하지만, for of 문은 배열에 자주 사용합니다.
배열 안에서 자료들을 하나씩 꺼내고 싶을 때 사용합니다.

for of 문은 iterable(반복 가능한)인 자료형들에만 적용이 가능합니다. (배열, 문자열, ...)
좀 더 정확히 말하자면, Symbol.iterator 이라는 메서드를 지니고 있는 자료형에 적용이 가능합니다.
Symbol.iterator반복문 출력을 가능하게 해주는 일종의 함수입니다.

console.log(fruitArr[Symbol.iterator]());

출력값 👇

Object [Array Iterator] {
  __proto__: { next: ƒ next() }
}

머 이렇게 나오는데요 😊
솔직히 for of 의 내부 작동원리를 또 따로 공부해야 이해가 가능할 것 같습니다
저두 잘 모르겠어요. 일단 그렇구나~ 하고 넘어가봅시다!

❗️그리고 객체에는 for of 문을 사용할 수 없습니다.
객체는 iterable 자료형이 아니어서,
for of 문을 사용하면 TypeError(TypeError: obj is not iterable)가 납니다.

💫 정리

🤹🏻‍♀️ for in 반복문은,

  • 객체에 사용
  • enumerable(열거가능한)한 프로퍼티를 반복
  • 임의의 순서로 반복
  • prototype 값도 반복

🤹🏻‍♀️ for of 반복문은,

  • 배열에 사용
  • iterable(반복가능한)인 자료형들에 사용
  • 순서대로 반복

이 정도로 우선 알아두고,
사용하면서 부분부분 지식을 더 채워가며 이해하는 편이 더 효율적일 것 같습니다. 😉
그럼 안뇽!



💁🏻‍♀️ 참조

https://velog.io/@hoon_dev/JavaScript-for-in-for-of-%EB%B0%98%EB%B3%B5%EB%AC%B8-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0

https://doozi0316.tistory.com/entry/JavaScript-for-in-for-of%EC%9D%98-%EC%B0%A8%EC%9D%B4

https://developerntraveler.tistory.com/122

profile
쓸모있는 기술자

0개의 댓글