JavaScript 실용적인 for 사용법
2023년 08월 15일어떤 for를 써야할까
JavaScript에는 여러 종류의 for loop이 있다. 하는 일은 크게 달라보이지 않아서 forEach
, for of
, for in
, for
중 어떤 함수가 쓰기에 적절한지 판단하기 어려웠다. 그래서 상황별로 어떤 for loop이 맞을지 한번 정리.
기준
코딩할 때 고민 할 만한 몇가지 기준으로 for loop을 나눠볼 수 있다.
- for 안에서 손쉽게 index 사용이 가능한지
- 비동기 처리 작업시 순차적으로 iteration이 작동하는지
- 중간에 break가 가능한지
- 성능적인 부분까지
1. for
전통적인(?) for loop이다. 문법 형태도 굉장히 직관적이다.
for (let i = 0; i < array.length; i++) {
}
index 사용
index를 기준으로 iterator를 만들면 쉽게 사용이 가능하다.
const fruits = ["딸기", "바나나", "망고"];
for (let i = 0; i < fruits.length; i++) {
console.log(`Index: ${i}, Value: ${fruits[i]}`);
}
비동기
loop 안에서 비동기 작업 수행을 위해 async
/await
를 사용하여 코드를 작성할 수 있다.
순차적으로 loop을 돌며 실행된다.
const makeIceCream = (fruit) => {
return new Promise((resolve) => {
setTimeout(() => {
resolve(`: 🍦 ${fruit}맛 아이스크림`);
}, 1000);
});
};
const fruits = ["딸기", "바나나", "망고"];
(async () => {
for (let i = 0; i < fruits.length; i++) {
console.log(`${fruits[i]}맛 아이스크림 나갑니다`);
const iceCream = await makeIceCream(fruits[i]);
console.log(iceCream);
}
})();
//로그 결과
딸기맛 아이스크림 나갑니다
: 🍦 딸기맛 아이스크림
바나나맛 아이스크림 나갑니다
: 🍦 바나나맛 아이스크림
망고맛 아이스크림 나갑니다
: 🍦 망고맛 아이스크림
break
조건에 맞게 루프를 중지할 수 있다.
2. forEach
forEach
는 다른 for와 좀 다르다. 가장 주의해서 봐야할 메서드
index 사용
forEach는 굉장히 편리하게 value, index를 사용할 수 있다. index는 두번째 파라미터로 사용 가능하다.
const fruits = ["딸기", "바나나", "망고"];
fruits.forEach((value, index) => {
console.log(`Index: ${index}, Value: ${value}`);
}
비동기 지원 X
아래 코드를 실행해보면 forEach안에서 await은 예상과 다르게 작동한다. forEach는 콜백 함수 안에 await을 게의치 않고 코드를 실행한다.
그렇기에 비동기코드가 순차적으로 실행되길 원한다면 forEach 말고 다른 for를 사용하자.
const makeIceCream = (fruit) => {
return new Promise((resolve) => {
setTimeout(() => {
resolve(`: 🍦 ${fruit}맛 아이스크림`);
}, 1000);
});
};
const fruits = ["딸기", "바나나", "망고"];
fruits.forEach(async (fruit) => {
console.log(`${fruit}맛 아이스크림 나갑니다`);
const iceCream = await makeIceCream(fruit);
console.log(iceCream);
});
//로그 결과
딸기맛 아이스크림 나갑니다
바나나맛 아이스크림 나갑니다
망고맛 아이스크림 나갑니다
: 🍦 딸기맛 아이스크림
: 🍦 바나나맛 아이스크림
: 🍦 망고맛 아이스크림
break
forEach loop내에서 break로 루프를 중지 할 수 없다. 위에 비동기 처리에서 알 수 있듯이 forEach는 순차적으로 진행되지 않기 때문에.
3. for in
index 사용
index 사용이 가능하다.
for in은 index를 기준으로 iteration을 한다.
const fruits = ["딸기", "바나나", "망고"];
for(const index in fruits){
console.log(`Index: ${index}, Value: ${array[index]}`);
}
비동기 지원
loop 안에서 비동기 작업 수행을 위해 async
/await
를 사용하여 코드를 작성할 수 있다.
(async () => {
for (const i in fruits) {
console.log(`${fruits[i]}맛 아이스크림 나갑니다`);
const iceCream = await makeIceCream(fruits[i]);
console.log(iceCream);
}
})();
break
조건에 맞게 루프를 중지할 수 있다.
4. for of
index 사용
index를 어찌어찌 꺼내서 사용할 수는 있지만 for of 자체로는 지원하지 않는다.
for of는 element를 기준으로 iteration을 한다
const fruits = ["딸기", "바나나", "망고"];
for(const element of fruits) {
console.log(element)
}
비동기 지원
loop 안에서 비동기 작업 수행을 위해 async
/await
를 사용하여 코드를 작성할 수 있다.
(async () => {
for (const fruit of fruits) {
console.log(`${fruit}맛 아이스크림 나갑니다`);
const iceCream = await makeIceCream(fruit);
console.log(iceCream);
}
})();
**for await of
**은 또 뭐야?
interation을 돌고자하는 array가 promise일 때 사용하는 것. for loop 안에서 동작하는 async/await와는 관련이 없다.
하지만 보통은 사용하지 않는다. 보통 순환하려는 array는 이미 다 resolve 된 이후에 for loop을 쓰니까.
break
조건에 맞게 루프를 중지할 수 있다.
성능
각각 for 마다 실행 시간이 좀 다르다.
const array = Array(1000000);
console.time("for");
for (let i = 0; i < array.length; i++) {}
console.timeEnd("for");
console.time("forEach");
array.forEach((_, index) => {});
console.timeEnd("forEach");
console.time("for of");
for (const _ of array) {
}
console.timeEnd("for of");
console.time("for in");
for (const _ in array) {
}
console.timeEnd("for in");
//로그
for: 2.253ms
forEach: 1.738ms
for of: 17.164ms
for in: 2.217ms
나머지와 다르게 for of가 특히 느리다. 6~10배 정도 더 느리게 작동한다.
하지만 iteration횟수가 적다면 크게 고려하지 않아도 될 듯하다. 상대적으로 느리지만 ms단위의 사소한 차이다.
참고
- https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Statements/for
- https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Statements/for...in
- https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach
- https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Statements/for...of
- https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Statements/for-await...of
TAGS
JAVASCRIPT