자바스크립트 배열 반복문 차이

·2021년 5월 16일
0

이 글은 https://thecodebarbarian.com/for-vs-for-each-vs-for-in-vs-for-of-in-javascript 을 일부 변역한 글입니다.

자바스크립트에 배열과 객체에 관한 많은 반복문들이 있고, 각각의 장단점들이 있습니다.
하지만 차이를 명확하게 모르고 있어서 쓰던 것만 쓰는 경우가 많은 것 같습니다.
이 글에서는 4가지 종류의 배열 반복문에 대해 설명합니다.

1. for(let i = 0; i < arr.length; i++)
2. arr.forEach((v, i) => { /* ... */ })
3. for (let i in arr)
4. for (const v of arr)

개요

forfor/in은 실제 element가 아닌 배열의 index를 사용합니다.

const arr = ['a', 'b', 'c'];
for (let i = 0; i < arr.length; ++i) {
  console.log(arr[i]);
}

for (let i in arr) {
  console.log(arr[i]);
}
//arr[i]을 사용해야 한다

하지만 for/offorEach()는 배열 element를 사용합니다.
forEach()는 배열의 index에 사용할 수 있고, for/of사용할 수 없습니다.

arr.forEach((v, i) => console.log(v));

for (const value of arr) {
  console.log(v);
}

숫자가 아닌 Property(속성)

자바스크립트에서는 배열 또한 객체입니다. 이는 배열에 숫자뿐 아니라 문자열 property를 추가할 수 있다는 걸 의미합니다.

const arr = ['a', 'b', 'c'];

typeof arr; // 'object'
arr["1"]; // 'b'

//숫자가 아닌 property 부여
arr.test = 'bad';

arr.test === arr['test'];
arr[1] === arr['1']; 
// true, 자바스크립트의 배열은 객체의 한 종류입니다.

for/in은 숫자가 아닌 property를 출력합니다. 하지만 나머지 반복문들은 무시합니다.

const arr = ['a', 'b', 'c'];
arr.test = 'bad';

for (let i in arr) {
  console.log(arr[i]);
}
// "a, b, c, bad" 출력

이는 배열 반복에 for/in를 쓰는 걸 피하는 이유가 됩니다.
나머지 반복문들과 직관적으로 다르게 행동하기 때문에 때로는 오류를 일으키게 됩니다.

const arr = ['a', 'b', 'c'];
arr.test = 'abc';

for (let i = 0; i < arr.length; ++i) {
  console.log(arr[i]);
}
//"a, b, c" 출력

arr.forEach((v, i) => console.log(i, v));
//"a, b, c" 출력

for (const v of arr) {
  console.log(v);
}
//"a, b, c" 출력

따라서, 의도적으로 상속된 또는 숫자가 아닌 property를 출력하고 싶은게 아니라면 for/in의 사용을 피하는게 좋습니다.

빈 Elements(요소)

자바스크립트는 배열의 빈 elements를 허용합니다. 밑의 배열은 문법적으로 유효할 뿐더러 그의 길이는 3입니다.

const arr = ['a',, 'c'];

arr.length; // 3

우리를 헷갈리게 만드는 것은 반복문들이 빈 elements['a',, 'c'] 와 undefined['a', undifined, 'c']를 구분한다는 점입니다.
아래에는 각각의 반복문들이 빈 elements['a',, 'c'] 대하는 법을 보여줍니다.

for (let i = 0; i < arr.length; ++i) {
  console.log(arr[i]);
}
//"a, undefined, c" 출력

arr.forEach(v => console.log(v));
//"a, c" 출력

for (let i in arr) {
  console.log(arr[i]);
}
//"a, c" 출력

for (const v of arr) {
  console.log(v);
}
//"a, undefined, c" 출력

for/infor.Each()는 빈 elements를 건너뛰고, forfor/of는 undefined로 출력합니다. for.Each()는 아마 문제를 일으킬 수 있습니다.
하지만, 이런 자바스크립트의 함정들은 JSON를 쓰면 없어집니다.

$ node
> JSON.parse('{"arr":["a","b","c"]}')
{ arr: [ 'a', 'b', 'c' ] }
> JSON.parse('{"arr":["a",null,"c"]}')
{ arr: [ 'a', null, 'c' ] }
> JSON.parse('{"arr":["a",,"c"]}')
SyntaxError: Unexpected token , in JSON at position 12

따라서, 유저 데이터에 대해 이런 걱정은 가지실 필요는 없습니다.

그러면 여기서 궁굼증이 생기실 겁니다. 그러면 undefined['a', undifined, 'c']는?
다행히 모든 반복문들이 "a, undefined, c" 를 출력합니다.

따라서, 빈 element에 대해 for/infor.Each()는 빈 elements를 건너뛰고, forfor/of는 undefined로 출력합니다.

결론

일반적으로 for/of은 자바스크립트에서 배열을 반복시킬때 가장 건장되는 방법입니다. for문 보다 휠씬 간결할 뿐아니라 for/inforEach()처럼 많은 예외도 가지지 않습니다.
for/of의 가장 큰 단점은 배열의 index을 쓰고 싶다면 Array#entries( )라는 추가 작업을 해야하고 forEach()처럼 연쇄작용을 하지 못합니다.
forEach()는 사용할 때에 주의를 가져야 하고, 드물게 사용됩니다. 하지만 코드들은 간결하게 하는 수많은 사례들이 있습니다.

profile
...

0개의 댓글