for in
은 객체에 대한 반복을 할 때 주로 사용된다.
예시를 살펴보자.
let testObj = {
yaya: 1000,
ho: 133,
naldo: 184,
nolja: 235,
toss: 49,
};
for (let key in testObj) {
console.log(key);
}
이런 식으로 객체의 key
에 접근할 때 사용된다.
결과는 아래와 같다.
yaya
ho
naldo
nolja
toss
key
가 나온다는 점에 주의하자.
만약 key
,value
를 모두 사용하고자 한다면 다음과 같이 사용할 수 있겠다.
for (let key in testObj) {
console.log(key, testObj[key]);
}
그렇다면 결과는?
yaya 1000
ho 133
naldo 184
nolja 235
toss 49
key
, value
가 알맞게 출력되는 것을 확인 할 수 있다.
for in
은 enumerable
한 프로퍼티에 대해서만 작동하는 문법이다.
...네...?? 그걸 제가 어떻게 알아요 ㅠㅠ
알 수 있는 방법이 있다.
Object.getOwnPropertyDescriptor()
메소드를 사용하면 된다.
사용법은 아래와 같다.
Object.getOwnPropertyDescriptor(obj, propertyName);
obj
자리에는 속성을 찾을 객체, propertyName
에는 설명이 검색될 속성명을 작성하면 된다.
그럼 위 예시를 활용해서 실제로 사용해보자.
Object.getOwnPropertyDescriptor(testObj, "yaya");
testObj
라는 객체의 yaya
라는 key
의 설명을 출력해라!!
콘솔을 찍어보면 아래와 같다.
{ value: 1000, writable: true, enumerable: true, configurable: true }
오..enumerable
이라는 key
에 true
라는 값이 들어있다.
즉, 이 프로퍼티는 enumerable
하다는 것이다.
문득, JS에서 배열 또한 object 속성이라는 것이 생각나서, 예시를 하나 만들어보았다.
let testArr = ["yaya", "ho", "naldo", "nolja", "toss"];
for (let prop in testArr) {
console.log(prop);
}
결과는 어떨까?
결과를 보기 전에, 배열은 enumerable
한지 먼저 살펴보자.
Object.getOwnPropertyDescriptor(testArr, "yaya");
과연 배열은 enumerable
할까?
undefined
엥? 아니 그럼 배열은 for in
못 써요?
아니다.
배열에 대해서 Object.getOwnPropertyDescriptor()
를 하려면 인덱스 번호를 적어야한다.
Object.getOwnPropertyDescriptor(testArr, 0);
0번 인덱스에 있는 프로퍼티에 대한 설명을 출력해라!!
{ value: 'yaya', writable: true, enumerable: true, configurable: true }
오 이번에는 제대로 출력된다!
enumerable
이 true
인 것을 확인 할 수 있다!
즉, 배열도 for in
을 사용할 수 있다.
그럼 위에서 for in
으로 콘솔을 찍은 값들을 살펴보자.
0
1
2
3
4
배열에 대해서는 인덱스가 출력되는 것을 확인 할 수 있다.
인덱스를 출력한다라...그렇다면 인덱스에 있는 값을 출력하려면 어떻게 해야할까?
for (let prop in testArr) {
console.log(testArr[prop]);
}
이렇게 써주면 된다. 객체 타입 데이터에서 value
를 뽑아내는 방법과 동일하다.
결과를 살펴보자.
yaya
ho
naldo
nolja
toss
짠! 드디어 배열의 원소가 출력이 된다.
다음 예시를 살펴보자.(이 예시는 hoon_dev님 블로그에서 가져왔습니다.)
let bookArray = [
"자바스크립트 완벽하게 이해하기",
32000,
"훈이",
"자바스크립트짱짱",
];
class Book {
constructor(title, price, author, publisher) {
(this.title = title),
(this.price = price),
(this.author = author),
(this.publisher = publisher);
}
}
Book.prototype.published_date = 20201220;
let book = new Book(...bookArray);
for (key in book) {
console.log(`key : ${key} / value : ${book[key]}`);
}
결과를 살펴보자.
key : title / value : 자바스크립트 완벽하게 이해하기
key : price / value : 32000
key : author / value : 훈이
key : publisher / value : 자바스크립트짱짱
key : published_date / value : 20201220
마지막 줄에 있는 것은 객체에 들어있던 값이 아니었다.
published_date
의 prototype
을 추가했더니 반복문에 같이 딸려 나온 것이다.
그러나 우리는 bookArray
라는 객체의 값만 필요하므로, 이 상황은 좋지 않다.
어떻게 하면 prototype
의 결과를 제외하고, 필요한 값들만 뽑아낼 수 있을까?
for (key in book) {
if (book.hasOwnProperty(key)) {
console.log(`key : ${key} / value : ${book[key]}`);
}
}
바로 key
의 존재 여부를 판단해주는 hasOwnProperty()
메소드를 사용하면 된다.
결과를 살펴보자.
key : title / value : 자바스크립트 완벽하게 이해하기
key : price / value : 32000
key : author / value : 훈이
key : publisher / value : 자바스크립트짱짱
이제 prototype
에 의한 값은 출력되지 않는 것을 확인 할 수 있다!
for of
는 주로 배열의 반복에 대하여 사용한다.
꼭 배열에만 사용해야 되는 것은 아니고 반복 가능한 객체라면 사용할 수 있다.
반복 가능한 객체란 무엇인가?
for...of 명령문은 반복가능한 객체 (Array, Map (en-US), Set, String, TypedArray, arguments 객체 등을 포함)에 대해서 반복하고...
- MDN docs -
그렇다. 저런 데이터를 반복 가능한 객체라고 한다.
애매하다. 더 정확하게 반복 가능한 객체를 정의하면 다음과 같다.
[Symbol.iterator] 속성을 가지고 있는 것
이 것을 어떻게 확인할 수 있느냐?
testArr[Symbol.iterator]();
알고싶은 대상(여기서는 testArr
라는 변수)에 [Symbol.iterator]()
을 사용하면 된다.
결과를 콘솔에 찍어보면, 다음과 같은 결과가 나온다.
Object [Array Iterator] {}
이런 결과가 나오면 이 객체는 반복 가능한 객체이다.
이제 사용 조건을 알았으니 사용법을 알아보자.
let testArr = ["yaya", "ho", "naldo", "nolja", "toss"];
for (let item of testArr) {
console.log(item);
}
for in
의 사용법과 똑.같.다.
다른 것은 결과뿐이다.
결과를 살펴보자.
yaya
ho
naldo
nolja
toss
for in
때와는 다르게 이번에는 바로 배열 원소에 접근할 수 있다!
그렇다면 객체에 대해서도 살펴보자.
let testObj = {
yaya: 1000,
ho: 133,
naldo: 184,
nolja: 235,
toss: 49,
};
console.log(testObj[Symbol.iterator]()); // 에러!!
객체에 대해서는 불가능하다.
객체는 반복 가능한 객체가 아니기 때문이다.
사용 방향이 다른듯 비슷한 두 방법에 대해서 알아봤다.
하지만 결국 중요한 것은 성능!
어떤 방법이 더 빠른지 살펴보자.
아래 이미지는 길이가 100인 배열에 대하여 테스트를 진행한 성능 지표이다.
for in
이 더 좋은 성능을 보인다..!
그러나 for in
은 성능 이전에 다양한 문제가 있었다.
결국 성능 비교에 대해, 어떤 방법이 더 좋은 방법인지 가려내기가 어렵다.
객체에는 for in
, 배열 등에는 for of
를 사용하는게 맞는 것 같다.
hoon_dev님 블로그
kkd927님 게시글
for in - MDN docs
Object.getOwnPropertyDescriptor() - Javascript Info
Object.getOwnPropertyDescriptor() - MDN docs