Javascript에는 객체와 배열을 반복 순회하는 여러 가지 방법이 존재합니다. 실제 코딩을 하면서 여러 방식들을 두루두루 사용해 보았지만 어떤 상황에 어떤 방식을 사용하는 것이 적합한지 항상 헷갈리는 것 같습니다. 그래서 이번 기회에 각 반복문의 특징에 대해 정리해보려고 합니다.
forEach
우선 가장 덜 헷갈리는 forEach부터 살펴보겠습니다.
let arr = [1, 2, 3];
arr.forEach((el, i, arr) => {
console.log(el);
});
// 1 2 3
forEach 의 콜백함수는 다음 세 가지 파라미터와 함께 호출될 수 있습니다.
- 처리할 현재 요소
- 처리할 요소의 인덱스
- forEach를 호출한 배열
forEach 는 엄밀히 말하면 반복'문'이 아니라 메서드입니다. Array의 prototype 객체 안에 선언된 함수이기 때문에 forEach는 배열에 대해서만 사용가능합니다. 아래와 같이 객체에 사용하려고 한다면 TypeError가 발생합니다.
let obj = { a: 1, b: 2, c: 3 };
obj.forEach((el, i) => {
console.log(el);
});
//TypeError: arr.forEach is not a function...
for-in VS for-of
for-in 과 for-of 는 도대체 뭐가 다른 걸까요?? 결론부터 말하자면
- for-in 은 객체에 있는 각 항목들에 대해 반복적인 동작을 할 수 있게 해 줍니다.
- for-of 는 반복 가능한 객체에 있는 각 항목들에 대해 반복적인 동작을 할 수 있게 해 줍니다.
말이 좀 어려우니 하나하나 살펴보도록 하겠습니다.
for-of
let arr = ["a", "b", "c"];
for (let value of arr) {
console.log(`value : ${value}`);
}
for-of 는 각 요소를 순회하며 요소의 값에 접근합니다. 콜백 함수가 필요 없다는 점만 뺀다면, 이런 동작 방식은 앞서 살펴본 forEach 와 비슷해 보입니다.
for-of는 forEach와 다르게 순회 중 continue, break, return 을 사용할 수 있다는 장점이 있습니다!!
아래 코드는 어떤 동작을 하게 될까요?
let obj = { a: 1, b: 2, c: 3 };
for (let value of obj) {
console.log(`value : ${value}`);
}
for-of 는 반복 가능한 객체에 대해서 사용할 수 있기 때문에 위와 같은 코드에선 TypeError가 발생하게 됩니다.
- 반복 가능한 객체에는 Array, Map, Set, String, TypedArray, arguments 객체 등이 있습니다. iterable Object에 대해선 추후에 다뤄보도록 하겠습니다.
- 사실 for-of 는 반복 가능한 객체라면 어떤 것에라도 사용할 수 있다는 것이 장점이기도 합니다!
2023.02.13 - [Javascript] - 자바스크립트 iterable 객체, for-io, 반복가능한 객체
자바스크립트 iterable 객체, for-io, 반복가능한 객체
이전에 제가 작성한 반복문의 종류에 관한 글에서 for-of는 '반복 가능한 객체에 있는 각 요소들에 대해 반복적인 동작을 할 수 있게 해 준다'라고 이야기한 적이 있습니다. 여기서 반복 가능한 객
do-it-bobby.tistory.com
참고사항
let arr = ["a", "b", "c"];
for (const [key, value] of arr.entries()) {
console.log(`key : ${key}, value : ${arr[key]}`);
}
위와 같이 for-of 도 Array.prototype.entries() 메서드를 사용하여 배열의 인덱스에 접근할 수 있습니다.
for-in
let arr = ["a", "b", "c"];
for (let key in arr) {
console.log(`key : ${key}, value : ${arr[key]}`);
}
for-in 의 경우 요소의 key를 통해 각 요소를 순회합니다.
Javascript에서는 배열도 객체의 한 종류이고 배열의 index 가 요소의 key 입니다!
그리고 for-in 은 객체에 대해서도 잘 동작합니다.
let obj = { a: 1, b: 2, c: 3 };
for (let key in obj) {
console.log(`key : ${key}, value : ${obj[key]}`);
}
for-in 사용의 위험성
많은 개발자들이 for-in 을 사용함에 있어 주의를 기울여야 한다고 말합니다. 그 이유는 무엇일까요?
다음의 코드를 살펴보겠습니다.
let obj = { a: 1, b: 2, c: 3 };
Object.prototype.fnc = function() {
console.log("fnc in Object");
}; // --- 1
for (let key in obj) {
console.log(`key : ${key}, value : ${obj[key]}`);
}
코드의 1번 부분에서 모든 객체가 상속하고 있는 Object의 prototype에 fnc 라는 메서드를 하나 추가하였습니다.
결과에서 볼 수 있듯이 for-in 을 사용하게 되면 해당 객체의 속성뿐만 아니라 객체가 상속하고 있는 속성까지도 접근하기 때문에 의도치 않은 결과가 나올 수 있습니다. 이러한 현상을 방지하기 위해선 hasOwnProperty 함수를 사용할 수 있습니다. 혹은 Object.keys() 를 이용하여 해당 객체의 key 값에 대해 순회할 수 있습니다.
let obj = { a: 1, b: 2, c: 3 };
Object.prototype.fnc = function() {
console.log("fnc in Object");
};
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
console.log(`key : ${key}, value : ${obj[key]}`);
}
}
자바스크립트의 코딩 스타일과 잠재된 위험성을 점검해 주는 JSLint에서도 for-in을 사용할 때 위와 같이 hasOwnProperty 함수로 객체의 속성인지를 검사할 것을 권장하고 있습니다.
이 외에도 for-in 은 객체를 순회할 때 속성들의 순서를 보장하지 않는다는 단점이 있습니다. 따라서 배열을 순회할 때 for-in 을 사용하는 것은 그리 좋은 생각이 아닙니다.
정리해 보자면,
forEach
- 배열에 사용가능
- 콜백에서 각 요소의 값과 인덱스를 매개변수로 받을 수 있음
for-of
- 반복 가능한 객체에 사용 가능(iteration protocol을 준수하는 객체)
- 일반 객체 사용 X, 각 요소의 값에 접근
- continue, break, return 을 사용할 수 있음
for-in
- 배열, 객체에 사용 가능
- 상속받은 값에도 접근 -> hasOwnProperty 로 속성 검사 필요
- continue, break, return 을 사용할 수 있음
'Javascript' 카테고리의 다른 글
Javascript 실행 컨텍스트, 호이스팅, 클로저의 이해(2) (0) | 2023.02.11 |
---|---|
Javascript 실행 컨텍스트, 호이스팅, 클로저의 이해(1) (0) | 2023.02.09 |
Javascript 이벤트 위임 패턴, 이벤트 전파 중단 (0) | 2023.01.19 |
[Javascript] Javascript event, 이벤트 전파란? (0) | 2023.01.03 |
[Javascript] Javascript event, Event Handler란 무엇인가 (0) | 2023.01.02 |
댓글