이 글은 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)
for
와 for/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/of
와 forEach()
는 배열 element를 사용합니다.
forEach()
는 배열의 index에 사용할 수 있고, for/of
사용할 수 없습니다.
arr.forEach((v, i) => console.log(v));
for (const value of arr) {
console.log(v);
}
자바스크립트에서는 배열 또한 객체입니다. 이는 배열에 숫자뿐 아니라 문자열 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를 허용합니다. 밑의 배열은 문법적으로 유효할 뿐더러 그의 길이는 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/in
와 for.Each()
는 빈 elements를 건너뛰고, for
와 for/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/in
와 for.Each()
는 빈 elements를 건너뛰고, for
와 for/of
는 undefined로 출력합니다.
일반적으로 for/of
은 자바스크립트에서 배열을 반복시킬때 가장 건장되는 방법입니다. for
문 보다 휠씬 간결할 뿐아니라 for/in
와 forEach()
처럼 많은 예외도 가지지 않습니다.
for/of
의 가장 큰 단점은 배열의 index을 쓰고 싶다면 Array#entries( )라는 추가 작업을 해야하고 forEach()
처럼 연쇄작용을 하지 못합니다.
forEach()
는 사용할 때에 주의를 가져야 하고, 드물게 사용됩니다. 하지만 코드들은 간결하게 하는 수많은 사례들이 있습니다.