본문 바로가기

JavaScript

[JavaScript] for in, for of 차이 알아보기

코드 리뷰할 때 for of에 대한 내용이 나와서 한번 정리해야겠다는 생각이 들었다.

for in과 for of 등 반복문을 사람마다 다양하게 사용하는 것을 발견하였고 각자 업무에 따른 의도가 있을 것 같다.

 


for in에 대한 공식 문서의 설명은 다음과 같다.

 

for...in문은 상속된 열거 가능한 속성들을 포함하여 객체에서 문자열로 키가 지정된 모든 열거 가능한 속성에 대해 반복합니다. (Symbol로 키가 지정된 속성은 무시합니다.)

 

for in은 객체에서 쓰이는 반복문으로 알고 있고

순서가 보장되지 않으며 key값으로 반복한다고 알고 있다.

 

설명을 봤을 때 알고 있는 내용이 포함되어있지만 "상속된 열거 가능한 속성"에 초점을 맞춰서 알아봐야겠다.

 

var arr = [5, 6, 7];

for(var key in arr) {
    console.log(key);	// 0, 1, 2
}

 

우선 배열 예제를 살펴봤다.

배열의 값이 아닌 index 값이 나타난다.

자바스크립트에서는 배열도 객체이므로 동작은 할 것이다.

 

하지만 공식문서에서 언급하고 있다..

 

for in을 배열에 사용하면 안 되는 이유를 명확히 설명하고 있다.

 

그렇다면 일반 객체는..?

 

var obj = {a:5, b:6, c:7};

for(var key in obj) {
    console.log(key);		// a, b, c
    console.log(obj[key]);	// 5, 6, 7
}

 

객체에서는 key 값을 표현하고 해당 키값으로 value를 참조할 수도 있다.

그럼 처음에 설명된 "상속된 열거 가능 속성"이란 무엇일까?

 

var obj = {a:5, b:6, c:7};

Object.prototype.objFunction = function() {console.log("FF")};

for(var key in obj) {
    console.log(key);		// a, b, c, objFunction
    console.log(obj[key]);	// 5, 6, 7, ƒ () {console.log("FF")}
}

 

Object에 새로운 속성을 추가해봤다.

for in을 통해 obj 객체뿐만 아니라 상속된 속성도 참조하여 반복한다.

 

for in은 이정도 알아보면 되겠고..

필요할 때 정확히 이해된 상태에서 사용하는 게 좋을 것 같다.

 


그렇다면 for of는..?

 

for...of 명령문은 반복 가능한 객체 (Array, Map, Set, String, TypedArray, arguments 객체 등을 포함)에 대해서 반복한다.

 

var obj = {a:'5', b:'6', c:'7'};

for(var key of obj) {
    console.log(key);
}

 

우선 일반 객체 변수 예제로 반복해봤다.

하지만 정상 동작되지 않고 iterable 하지 않다면서 오류가 난다.

 

일반적으로 사용하는 객체는 반복 가능하지 않다는 뜻이다.

 

그렇다면 배열은..?

 

var arr = [5, 6, 7];
var str = "abcd";

for(var val of arr) {
    console.log(val);	// 5, 6, 7
}

for(var ch of str) {
    console.log(ch);	// a, b, c, d
}

 

for in과 다르게 배열의 값이 반환된다.

문자열을 반복하여 문자를 하나씩 받아올 수 있다는 것도 특이했다.

또한 배열의 인덱스를 가져올 수 없다는 점도 알아둬야겠다.

 

단순하게 반복 가능한 객체의 값을 참조하기 위한 반복문으로 사용하면 좋을 것 같다.

 


그렇다면 for of와 for in의 차이점은 무엇일까?

 

for...in 루프는 객체의 모든 열거가능한 속성에 대해 반복합니다.
for...of 구문은 컬렉션 전용입니다. 모든 객체보다는, [Symbol.iterator] 속성이 있는 모든 컬렉션 요소에 대해 이 방식으로 반복합니다.

 

Object.prototype.objCustom = function () {};
Array.prototype.arrCustom = function () {};

let iterable = [3, 5, 7];
iterable.foo = "hello";

for (let i in iterable) {
  console.log(i); // logs 0, 1, 2, "foo", "arrCustom", "objCustom"
}

for (let i of iterable) {
  console.log(i); // logs 3, 5, 7
}

 

공식문서의 설명과 예제이다.

위의 예제를 참고해서 이해하면 되겠고

단순하게 기억하려면 객체 반복은 for in, 배열 반복은 for of으로 알고 있으면 되겠다.

 

쓰임새가 다르지만 속도면에서는 어떨지 궁금했다.

기존 for문과 한번 비교해보기로 했다.

 

var sum = 0;
var arr = [];
for(var i=0; i<1000000; i++) {
    arr[i] = i+1;
}

console.time("time");

// case 1 : 200 ~ 300 ms
for(var val in arr) {
    sum += val;
}

// case 2 : 27 ~ 30 ms
for(var val of arr) {
    sum += val;
}

// case 3 : 19 ~ 22 ms
for(var i=0; i<1000000; i++) {
    sum += arr[i];
}

console.timeEnd("time");

 

배열 예제로 단순 속도 비교를 해봤다.

100% 확실하지는 않지만 반복문 별로 어느 정도 차이 나는지 파악할 수 있을 것 같다.

 

for in문이 예상대로 다른 반복문에 비해 느렸다.

for문과 for of문은 비슷하지만 근소하게 for문이 빠른 결과로 나타났다.

단순 예제여서 그럴 수 있고 for of만의 장점들이 있기 때문에 상황에 맞게 잘 사용하면 되겠다.

 

공식 문서와 예제로 for in과 for of의 차이에 대해서 알아봤다.

단순하지만 놓치기 쉬운 부분이라 앞으로는 정확히 이해하고 사용하도록 해야겠다!

 

'JavaScript' 카테고리의 다른 글

[JavaScript] this 알아보기  (0) 2022.07.31