JavaScript에서 배열을 반복


3144

Java에서는 for다음과 같이 루프를 사용 하여 배열의 객체를 순회 할 수 있습니다 .

String[] myStringArray = {"Hello", "World"};
for (String s : myStringArray)
{
    // Do something
}

JavaScript에서도 같은 작업을 수행 할 수 있습니까?


5
좋아, 약간 혼란스러워, 객체에 액세스 할 때 향상된 for 루프를 사용해도 괜찮습니까? 그리고 하나를 채우는 데 순차적 인 것을 사용합니까? 이 올바른지?
Mark Szymanski 2018 년

45
아니, 당신이 할 수 있도록 배열 개체, 숫자 인덱스가 정말 간단 반복 숫자 순서대로 그 인덱스를이 지남에 따라, 순차적 루프 보장하지만 향상된 for-in 루프 자가 열거 특정 순서없이, 객체 특성, 또한 상속 된 속성을 열거합니다. ..에 대한 반복 배열을 통해 순차적 루프는 항상 추천 ...
CMS


6
jsben.ch/#/Q9oD5는 <배열을 통해 반복을 위해 여기에서 솔루션의 무리의 벤치 마크 =
EscapeNetscape

3
@CMS 아니요, 간단하지 않습니다. 다른 모든 언어에서는 정말 간단합니다. 그것은 당신이 JS에 터무니없이 복잡 in하고 of그이 모두 사용할 수 있으며, 다른 일을. 그런 다음 forEach추악하고 성가신 색인 기반 반복 기능도 있습니다. 다른 모든 현대 언어는 놀라움이나 혼란없이 컬렉션을 쉽고 간단하게 반복합니다. JS도 가능하지만 그렇지 않습니다.
jpmc26

답변:


3957

몇 가지 옵션이 있습니다.

1. 순차 for루프 :

var myStringArray = ["Hello","World"];
var arrayLength = myStringArray.length;
for (var i = 0; i < arrayLength; i++) {
    console.log(myStringArray[i]);
    //Do something
}

찬성

  • 모든 환경에서 작동
  • 제어문을 사용 break하고 continue플로우 할 수 있습니다

단점

  • 너무 자세한
  • 피할 수 없는
  • 일대일 오류가 발생 하기 쉽습니다 (때때로 펜스 포스트 오류 라고도 함 )

2. Array.prototype.forEach

ES5 사양은 많은 유익한 배열 방법 중 하나를 도입했으며 배열 Array.prototype.forEach을 반복하는 간결한 방법을 제공합니다.

const array = ["one", "two", "three"]
array.forEach(function (item, index) {
  console.log(item, index);
});

ES5 사양이 출시 된 시점 (2009 년 12 월)에 거의 10 년이 지난 지금 데스크톱, 서버 및 모바일 환경의 거의 모든 최신 엔진에 의해 구현되었으므로 안전하게 사용할 수 있습니다.

그리고 ES6 화살표 함수 구문을 사용하면 훨씬 간결합니다.

array.forEach(item => console.log(item));

화살표 기능은 고대 플랫폼 (예 : IE11)을 지원할 계획이 아니라면 널리 구현됩니다. 당신은 또한 안전합니다.

찬성

  • 매우 짧고 간결합니다.
  • 선언적

단점

  • break/를 사용할 수 없습니다continue

일반적으로 break배열 요소를 반복하기 전에 필터링하여 명령형 루프 에서 벗어날 필요성을 대체 할 수 있습니다 . 예를 들면 다음과 같습니다.

array.filter(item => item.condition < 10)
     .forEach(item => console.log(item))

당신이 배열을 반복하는 경우 명심 가에서 다른 배열을 구축하기 위해 , 당신은 사용해야을 map나는 여러 번 있도록이 안티 패턴을 보았다.

안티 패턴 :

const numbers = [1,2,3,4,5], doubled = [];

numbers.forEach((n, i) => { doubled[i] = n * 2 });

지도의 적절한 사용 사례 :

const numbers = [1,2,3,4,5];
const doubled = numbers.map(n => n * 2);

console.log(doubled);

또한 배열을 값 으로 줄이려고 하는 경우 (예를 들어, 숫자 배열을 합산하려는 경우) reduce 메소드를 사용해야합니다 .

안티 패턴 :

const numbers = [1,2,3,4,5];
const sum = 0;
numbers.forEach(num => { sum += num });

Reduce의 적절한 사용 :

const numbers = [1,2,3,4,5];
const sum = numbers.reduce((total, n) => total + n, 0);

console.log(sum);

3. ES6 for-of진술

ES6 표준은 반복 가능한 객체의 개념을 소개하고 데이터를 순회하기위한 새로운 for...of구문 인 명령문 을 정의합니다 .

이 문장은 모든 종류의 반복 가능한 객체와 생성기 ( [Symbol.iterator]속성 이있는 객체 )에서도 작동합니다.

ES6에는 배열 객체가 정의에 따라 내장 이터 러블이므로이 명령문을 사용할 수 있습니다.

let colors = ['red', 'green', 'blue'];
for (const color of colors){
    console.log(color);
}

찬성

  • 다양한 객체를 반복 할 수 있습니다.
  • 일반적인 흐름 제어문을 사용할 수 있습니다 ( break/continue )을 .
  • 직렬 비동기 값을 반복하는 데 유용합니다.

단점

사용하지 마세요 for...in

@zipcodeman은 for...in명령문 사용을 제안 하지만 배열 반복을 for-in피하려면 해당 명령문을 열거해야합니다. 오브젝트 특성 입니다.

다음과 같은 이유로 배열과 같은 객체에 사용해서는 안됩니다.

  • 반복 순서는 보장되지 않습니다. 배열 인덱스는 숫자 순서대로 방문 할 수 없습니다.
  • 상속 된 속성도 열거됩니다.

두 번째 요점은 예를 들어 Array.prototype 메소드를 포함 오브젝트를 해당 특성도 열거됩니다.

예를 들면 다음과 같습니다.

Array.prototype.foo = "foo!";
var array = ['a', 'b', 'c'];

for (var i in array) {
    console.log(array[i]);
}

위의 코드는 콘솔 로그 "a", "b", "c"및 "foo!"입니다.

네이티브 프로토 타입 기능 보강 (예 : MooTools)에 크게 의존하는 라이브러리를 사용하는 경우 특히 문제가됩니다.

for-in문은 내가 이전에이 말한대로 열거 예를 들어, 개체 속성을 :

var obj = {
    "a": 1,
    "b": 2,
    "c": 3
};

for (var prop in obj) {
    if (obj.hasOwnProperty(prop)) { 
        // or if (Object.prototype.hasOwnProperty.call(obj,prop)) for safety...
        console.log("prop: " + prop + " value: " + obj[prop])
    }
}

위의 예제 hasOwnProperty에서이 메서드를 사용하면 고유 한 속성 , 즉 개체에 물리적으로있는 속성 만 상속 된 속성 만 열거 할 수 있습니다 .

다음 기사를 읽는 것이 좋습니다.


21
이것은 (CMS 그 자체로) 이유입니다 stackoverflow.com/questions/1885317/...
OscarRyz

15
@DoubleGras, 나는 그것이 모든 사람이 공유하지 않는 의견이라고 생각합니다. 참조 : stackoverflow.com/questions/5752906/… 또는 groups.google.com/forum/?fromgroups#!topic/jsmentors/…
Matthijs Wessels

3
길이를 캐시해야한다고 생각하는 사람은 ... 내 대답을 참조하십시오. 단일 액세스하지 않아도 캐시하지는 않습니다. for (var i = 0, item; item = myStringArray [i]; 내가 ++) {여기에 / * 사용 항목 * /}
스테인 드 위트

15
@StijndeWitt 아니, 휴식 때문에 당신은 어떤이있는 경우 "falsey" 배열에 값을 : false, undefined, 0, "", NaN.
Phrogz

6
jsperf.com/caching-array-length/4 다음은 자바 스크립트 루프에서 배열의 길이를 캐싱 할 가치가 있는지 테스트하는 방법입니다.
Enrico

1114

예, 구현 에 ECMAScript 2015에 도입 된 for...of 기능 ( "하모니"릴리스)이 포함되어 있다고 가정하면 요즘 꽤 안전한 가정입니다.

다음과 같이 작동합니다.

// REQUIRES ECMASCRIPT 2015+
var s, myStringArray = ["Hello", "World"];
for (s of myStringArray) {
  // ... do something with s ...
}

ECMAScript 2015는 블록 범위 변수도 제공하므로 더 좋습니다.

// REQUIRES ECMASCRIPT 2015+
const myStringArray = ["Hello", "World"];
for (const s of myStringArray) {
  // ... do something with s ...
}
// s is no longer defined here

( s반복마다 변수 가 다르지만 const루프 본문 내에서 수정되지 않는 한 선언 할 수 있습니다 .)

희소 배열에 대한 참고 사항 : JavaScript의 배열은 실제로보고 된만큼 많은 항목을 저장할 수 없습니다 length. 그보고 된 숫자는 단순히 값이 저장되는 가장 높은 인덱스보다 하나 더 큽니다. 배열이 길이로 표시된 것보다 적은 수의 요소를 보유하면 희소 하다고합니다 . 예를 들어 인덱스 3, 12 및 247에만 항목이있는 배열을 갖는 것이 합법적입니다. 누락 된 요소들, 또는 당신은 실제로 존재하는 요소를 처리 할 수 있습니까? 두 가지 접근 방식에 대한 많은 응용 프로그램이 있습니다. 배열을 사용하는 대상에 따라 다릅니다.length이 실제로 3 개 값을 저장하고 있지만 이러한 배열은, (248)로보고된다. 다른 인덱스에서 항목에 액세스하려고하면 배열에 undefined값이 있는 것으로 나타납니다 . 따라서 배열을 "루프 스루"하려는 경우 대답해야 할 질문이 있습니다. 길이와 프로세스로 표시되는 전체 범위를 루핑 하시겠습니까?undefined

for.. 을 사용하여 배열을 반복 of하면 루프의 본문이 실행되고 배열에 실제로 존재하지 않는 항목 lengthundefined대해 루프 제어 변수가 설정됩니다 . "함께하는 것"코드의 세부 사항에 따라 해당 동작이 원하는 것일 수 있지만 그렇지 않은 경우 다른 방법을 사용해야합니다.

물론, 일부 개발자들은 선택의 여지가 있지만, 때문에 그들은 아직 지원하지 않는 자바 스크립트의 버전을 타겟팅하고 어떤 이유로, 어쨌든 다른 접근 방법을 사용하는 것이 for... of.

JavaScript 구현이 ECMAScript 사양 의 이전 버전 (예 : 9 이전의 Internet Explorer 버전을 배제)을 준수 Array#forEach하는 경우 루프 대신 반복자 메서드를 사용할 수 있습니다 . 이 경우 배열의 각 항목에서 호출 할 함수를 전달합니다.

var myStringArray = [ "Hello", "World" ];
myStringArray.forEach( function(s) { 
     // ... do something with s ...
} );

달리 for... of, .forEach실제로 어레이에 존재하는 요소의 함수를 호출한다. 세 개의 요소와 길이가 248 인 가상 배열을 전달하면 248 번이 아니라 함수를 세 번만 호출합니다. 또한 누락 된 요소와 실제로 설정된 요소를 구분합니다 undefined. 후자의 경우 여전히 함수를 호출 undefined하여 인수로 전달 합니다. 이것이 희소 배열을 처리 .forEach하는 방법이라면 통역사가 for...을 지원하더라도 갈 수있는 방법 일 수 있습니다 of.

모든 버전의 JavaScript 에서 작동하는 마지막 옵션 은 명시적인 계산 루프 입니다. 단순히 0에서 길이보다 1을 작게 세어 카운터를 인덱스로 사용하십시오. 기본 루프는 다음과 같습니다.

var i, s, myStringArray = [ "Hello", "World" ], len = myStringArray.length;
for (i=0; i<len; ++i) {
  s = myStringArray[i];
  // ... do something with s ...
}

이 방법의 장점 중 하나는 희소 배열을 처리하는 방법을 선택할 수 있다는 것입니다. 위의 코드는 루프 본문을 전체 length시간 동안 실행하며 누락 된 요소는 .. 과 같이 s설정됩니다 . 대신에 희소 배열의 실제로 존재하는 요소 만 처리하려는 경우 인덱스에 간단한 테스트를 추가 할 수 있습니다 .undefinedforof.forEachin

var i, s, myStringArray = [ "Hello", "World" ], len = myStringArray.length;
for (i=0; i<len; ++i) {
  if (i in myStringArray) {
    s = myStringArray[i];
    // ... do something with s ...
  }
}

myStringArray.length루프 값에 전체 표현식 을 포함하는 것과 달리 로컬 변수에 길이 값을 지정하면 매번 특성 검색을 건너 뛰기 때문에 성능이 크게 달라질 수 있습니다. 내 컴퓨터에서 Rhino를 사용하면 속도가 43 % 향상됩니다.

다음과 같이 루프 초기화 절에서 수행 된 길이 캐싱을 볼 수 있습니다.

var i, len, myStringArray = [ "Hello", "World" ];
for (len = myStringArray.length, i=0; i<len; ++i) {

명시 적 카운팅 루프는 원하는 경우 각 값의 인덱스에 액세스 할 수 있음을 의미합니다. 인덱스는 전달한 함수에 추가 매개 변수로 전달 forEach되므로 다음과 같이 액세스 할 수도 있습니다.

myStringArray.forEach( function(s, i) {
   // ... do something with s and i ...
});

for... of각 객체와 관련된 색인을 제공하지는 않지만 반복하는 객체가 실제로 Array( for.. of이 방법이 없을 수있는 다른 반복 가능한 유형에 작동하는 경우) Array를 사용할 수 있습니다 #entries 메소드를 사용하여 [index, item] 쌍의 배열로 변경 한 다음 반복합니다.

for (const [i, s] of myStringArray.entries()) {
  // ... do something with s and i ...
}

for... in다른 사람에 의해 언급 구문은 객체의 속성에 걸쳐 반복입니다; JavaScript의 Array는 숫자 속성 이름 (및 자동으로 업데이트 된 length속성)을 가진 객체이기 때문에 이론적으로 Array를 반복 할 수 있습니다. 그러나 문제는 그 자체가 숫자 속성 값으로 제한되지 않는다는 것입니다 (메소드조차도 실제로 값이 클로저 인 속성 일뿐입니다). 따라서 배열을 반복하는 데 for... in구문을 사용해서는 안됩니다 .


21
코드가 충분한 횟수만큼 호출 되면 일부 인터프리터 (예 : V8)는 배열의 길이를 자동으로 캐시하고 길이가 루프에 의해 수정되지 않은 것을 감지합니다. 길이 캐싱은 여전히 ​​좋지만 실제로 차이를 만들기에 충분한 시간을 코드에서 호출하면 속도가 향상되지 않을 수 있습니다.
Phrogz 2016 년

2
@ mark-reed i in myStringArray예제에서 왜 사용했는지 설명해 주 시겠습니까? 그것은 어떻게 거짓 일 수 있습니까?
Denis V

2
@DenisV : 거짓. a=[1,2,3,4]; delete a[2]; for (j in a) { console.log(j); } 출력은 0, 1, 3, 4 a.length입니다. 여전히 5입니다.
Mark Reed

1
나는 제안하지 않습니다 for j in a. 나는 in당신이 주장한대로 모든 인덱스를 표시하고 0과 0 사이에 하나가 없다는 것을 보여줌으로써 검사가 중복되지 않는다는 것을 증명하고 length-1있습니다. 나는 또한 단지 인쇄 한 수 2 in a실로 인 false당신이 불가능하다고 말했다는 사실에도 불구하고.
Mark Reed

2
@GrijeshChauhan-맞습니다. 예를 들어, 버전 8을 통한 IE는이를 지원하지 않습니다. 이 질문을 참조하십시오 .
Mark Reed

442

당신은 사용할 수 있습니다 map또한 같은 다른 언어로 가능한 기능적인 프로그래밍 기술이다, 파이썬하스켈 .

[1,2,3,4].map( function(item) {
     alert(item);
})

일반적인 구문은 다음과 같습니다.

array.map(func)

일반적으로 func배열의 항목 인 하나의 매개 변수를 사용합니다. 그러나 JavaScript의 경우 항목의 인덱스 인 두 번째 매개 변수와 배열 자체 인 세 번째 매개 변수를 사용할 수 있습니다.

의 반환 값 array.map은 다른 배열이므로 다음과 같이 사용할 수 있습니다.

var x = [1,2,3,4].map( function(item) {return item * 10;});

이제 x는 [10,20,30,40]입니다.

함수를 인라인으로 작성할 필요는 없습니다. 별도의 기능 일 수 있습니다.

var item_processor = function(item) {
      // Do something complicated to an item
}

new_list = my_list.map(item_processor);

이는 다음과 같습니다.

 for (item in my_list) {item_processor(item);}

당신이를 제외하고는 new_list.


7
아니요,하지만 더 강력 할 수 있습니다. 이 체크 아웃 joelonsoftware.com/items/2006/08/01.html
하센

97
이 특정 예제는 아마도을 사용하여 더 잘 구현 될 것입니다 Array.forEach. map새 배열을 생성하기위한 것입니다.
harto

21
Array.prototype.map메소드는 ECMAScript 5th Edition Standard의 일부인 @hasen 은 아직 모든 구현에서 사용할 수 없습니다 (예 : IE가 부족함) . 배열 을 반복 하기 위해 Array.prototype.forEach메소드가 더 의미 적으로 정확 하다고 생각합니다. 자세한 내용은 내 답변을 참조하십시오 :)
CMS

3
차이 forEachmap이전의 반복의 결과를 반환하지 않는다는 점이다. map(때로는 일명 collect이지만와는 매우 다른 경우 apply)는 배열의 각 요소를 해당 결과로 변환하기위한 것입니다. 그것은 일대일 매핑 이므로 이름입니다. reduce(전체 배열에서 단일 결과 filter를 생성 함 ) 및 (원래 배열의 하위 집합을 생성 함 ) 등 을 포함하는 전체 연산 제품군의 일부입니다 . forEach각 요소로 무언가를 수행 하는 반면 , 의미는 지정되지 않았습니다.
Mark Reed

4
실제로 무언가를 매핑하지 않는 경우 [] .map을 사용하면 오도하기 때문에 Downvote. [] .forEach는 의미 론적 의미를 가지며 동일한 세 개의 인수를 함수에 전달합니다.
gengkev

120

JavaScript에서는 for-in 루프를 사용하여 Array를 반복하는 것이 좋지 않지만 다음 for과 같은 루프 를 사용하는 것이 좋습니다 .

for(var i=0, len=myArray.length; i < len; i++){}

또한 배열 길이를 "캐싱"합니다. 자세한 내용을 보려면 주제에 대한 내 게시물을 읽으십시오 .


2
myArray.forEach (function (obj) {}); 여전히 최고입니다
Jan Sverre

작은 개선 : ++i대신 사용할 수 있습니다i++
roberkules

14
++i현대 컴파일러는 오래 전에 :) 이후 for 루프에서 당신을 위해 할 것이 오래된 학교 최적화입니다 stackoverflow.com/a/1547433/1033348
ngryman

6
이 루프를 조심해서 사용해야합니다. 나는 그것을 사용하기 시작했고 한 가지 실수로 버그를 추적하기가 어려웠습니다. : 당신이 둥지 같은 두 개의 루프의 경우 jsfiddle.net/KQwmL/1을 . 두 루프에서 var len의 이름을 다르게 지정해야합니다. 그렇지 않으면 두 번째 루프가 첫 번째 len을 덮어 씁니다.
Rui Marques

1
Rui Marques-변수 이름을 지정 i_stop하거나 i_end대신 사용할 수 있습니다 len. 그것은 읽을 수있는 것처럼 (더 이상 그렇지 않다면!), 당신은 자연스럽게 이런 종류의 문제를 피할 것입니다 (다른 루프가 예를 들어 오기 때문에 j_stop).
Chip Hogg 2018 년

119

for (myStringArray의 문자) {

(직접 질문에 대답 : 지금 할 수 있습니다!)

대부분의 다른 답변은 옳지 만 ECMA Script  6  2015 가 반복, for..of루프 를 수행하기위한 새로운 메커니즘을 도입하고 있다고 언급하지는 않습니다 .

이 새로운 구문은 자바 스크립트에서 배열을 반복하는 가장 우아한 방법입니다 (반복 색인이 필요하지 않은 한).

현재 Firefox 13 이상, Chrome 37 이상에서 작동하며 다른 브라우저에서는 기본적으로 작동하지 않습니다 (아래 브라우저 호환성 참조). 운 좋게도 오늘날 차세대 기능을 사용할 수 있는 JS 컴파일러 (예 : Babel )가 있습니다.

노드에서도 작동합니다 (버전 0.12.0에서 테스트했습니다).

배열 반복

// You could also use "let" instead of "var" for block scope.
for (var letter of ["a", "b", "c"]) { 
   console.log(letter); 
}

객체 배열 반복

var band = [
  {firstName : 'John', lastName: 'Lennon'}, 
  {firstName : 'Paul', lastName: 'McCartney'}
];

for(var member of band){
  console.log(member.firstName + ' ' + member.lastName); 
}

생성기 반복 :

(예 : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of 에서 추출 )

function* fibonacci() { // a generator function
  let [prev, curr] = [1, 1];
  while (true) {
    [prev, curr] = [curr, prev + curr];
    yield curr;
  }
}

for (let n of fibonacci()) {
  console.log(n);
  // truncate the sequence at 1000
  if (n >= 1000) {
    break;
  }
}

호환성 테이블 : http://kangax.github.io/es5-compat-table/es6/#For..of 루프

사양 : http://wiki.ecmascript.org/doku.php?id=harmony:iterators

}


ES6를 사용하는 경우 const s대신var s
joeytwiddle

큰 배열 내 테스트에서 사용이 var s of arrnodejs에서 인덱스로 요소를위한 루프 간단한 카운터를 사용하여 검색에 비해 거의 두 배 (1.9 배) 실행 시간입니다
theferrit32

첫 번째 줄과 마지막 줄에서 왜 이상한 것들입니까?
Peter Mortensen

91

Opera, Safari, Firefox 및 Chrome은 이제 많은 공통 루프를 최적화하기 위해 일련의 향상된 배열 방법을 공유합니다.

모두 필요하지는 않지만 매우 유용하거나 모든 브라우저에서 지원하는 경우에 유용합니다.

Mozilla Labs는 자신과 WebKit이 모두 사용 하는 알고리즘을 공개하여 직접 추가 할 수 있습니다.

필터 는 일부 조건 또는 테스트를 만족하는 항목 배열을 반환합니다.

every 는 모든 배열 구성원이 테스트를 통과하면 true를 반환합니다.

일부 는 테스트를 통과하면 true를 반환합니다.

forEach 는 각 배열 멤버에서 함수를 실행하며 아무 것도 반환하지 않습니다.

map 은 forEach와 유사하지만 각 요소에 대한 연산 결과의 배열을 리턴합니다.

이러한 메소드는 모두 첫 번째 인수에 대한 함수를 취하고 선택적인 두 번째 인수를 갖습니다.이 인수는 함수를 반복 할 때 배열 멤버에 적용하려는 범위를 갖는 오브젝트입니다.

필요할 때까지 무시하십시오.

indexOflastIndexOf 는 해당 인수와 정확히 일치하는 첫 번째 또는 마지막 요소의 적절한 위치를 찾습니다.

(function(){
    var p, ap= Array.prototype, p2={
        filter: function(fun, scope){
            var L= this.length, A= [], i= 0, val;
            if(typeof fun== 'function'){
                while(i< L){
                    if(i in this){
                        val= this[i];
                        if(fun.call(scope, val, i, this)){
                            A[A.length]= val;
                        }
                    }
                    ++i;
                }
            }
            return A;
        },
        every: function(fun, scope){
            var L= this.length, i= 0;
            if(typeof fun== 'function'){
                while(i<L){
                    if(i in this && !fun.call(scope, this[i], i, this))
                        return false;
                    ++i;
                }
                return true;
            }
            return null;
        },
        forEach: function(fun, scope){
            var L= this.length, i= 0;
            if(typeof fun== 'function'){
                while(i< L){
                    if(i in this){
                        fun.call(scope, this[i], i, this);
                    }
                    ++i;
                }
            }
            return this;
        },
        indexOf: function(what, i){
            i= i || 0;
            var L= this.length;
            while(i< L){
                if(this[i]=== what)
                    return i;
                ++i;
            }
            return -1;
        },
        lastIndexOf: function(what, i){
            var L= this.length;
            i= i || L-1;
            if(isNaN(i) || i>= L)
                i= L-1;
            else
                if(i< 0) i += L;
            while(i> -1){
                if(this[i]=== what)
                    return i;
                --i;
            }
            return -1;
        },
        map: function(fun, scope){
            var L= this.length, A= Array(this.length), i= 0, val;
            if(typeof fun== 'function'){
                while(i< L){
                    if(i in this){
                        A[i]= fun.call(scope, this[i], i, this);
                    }
                    ++i;
                }
                return A;
            }
        },
        some: function(fun, scope){
            var i= 0, L= this.length;
            if(typeof fun== 'function'){
                while(i<L){
                    if(i in this && fun.call(scope, this[i], i, this))
                        return true;
                    ++i;
                }
                return false;
            }
        }
    }
    for(p in p2){
        if(!ap[p])
            ap[p]= p2[p];
    }
    return true;
})();

1
추가 : IE 버전 9를 참조 이후 대해 forEach를 지원 대해 forEach 방법 MSDN을
rwitzel

75

소개

대학 시절부터 Java, JavaScript, Pascal, ABAP , PHP, Progress 4GL, C / C ++ 및 아마도 내가 생각할 수없는 다른 언어로 프로그래밍했습니다.

모두 고유 한 언어 특성이 있지만 이러한 각 언어는 동일한 기본 개념을 많이 공유합니다. 이러한 개념에는 프로 시저 / 함수,- IF문,- FOR루프 및- WHILE루프가 포함됩니다.


전통적인 for루프

전통적인 for루프에는 세 가지 구성 요소가 있습니다.

  1. 초기화 : look 블록이 처음 실행되기 전에 실행
  2. 조건 : 루프 블록이 실행될 때마다 조건을 확인하고 false 인 경우 루프를 종료합니다.
  3. 추후 : 루프 블록이 실행될 때마다 수행

이 세 구성 요소는 ;기호로 서로 분리되어 있습니다 . 이 세 가지 구성 요소 각각에 대한 내용은 선택 사항이므로 다음은 for가능한 가장 작은 루프입니다.

for (;;) {
    // Do stuff
}

물론, 당신은 포함해야합니다 if(condition === true) { break; } 또는 if(condition === true) { return; }그 내부 어딘가 for가 실행 중지 갈 수 -loop을.

그러나 일반적으로 초기화는 인덱스를 선언하는 데 사용되며 조건을 사용하여 해당 인덱스를 최소 또는 최대 값과 비교하고 이후에 인덱스를 증가시키는 데 사용됩니다.

for (var i = 0, length = 10; i < length; i++) {
    console.log(i);
}

전통적인 for루프를 사용 하여 어레이를 반복

배열을 반복하는 전통적인 방법은 다음과 같습니다.

for (var i = 0, length = myArray.length; i < length; i++) {
    console.log(myArray[i]);
}

또는 뒤로 루프하는 것을 선호하는 경우 다음을 수행하십시오.

for (var i = myArray.length - 1; i > -1; i--) {
    console.log(myArray[i]);
}

그러나 예를 들어 다음과 같은 많은 변형이 가능합니다.

for (var key = 0, value = myArray[key], length = myArray.length; key < length; value = myArray[++key]) {
    console.log(value);
}

... 또는 이건 ...

var i = 0, length = myArray.length;
for (; i < length;) {
    console.log(myArray[i]);
    i++;
}

... 또는 이것 :

var key = 0, value;
for (; value = myArray[key++];){
    console.log(value);
}

가장 잘 작동하는 것은 주로 개인적인 취향과 구현중인 특정 사용 사례의 문제입니다.

이러한 각 변형은 매우 오래된 브라우저를 포함하여 모든 브라우저에서 지원됩니다!


while루프

for루프에 대한 한 가지 대안 은 while루프입니다. 배열을 반복하려면 다음을 수행하십시오.

var key = 0;
while(value = myArray[key++]){
    console.log(value);
}

기존 for루프 와 마찬가지로 while루프는 가장 오래된 브라우저에서도 지원됩니다.

또한 모든 while 루프를 루프로 다시 작성할 수 있습니다 for. 예를 들어, 위의 while루프는 다음과 같은 방식으로 작동합니다 for.

for(var key = 0; value = myArray[key++];){
    console.log(value);
}

For...infor...of

JavaScript에서 다음을 수행 할 수도 있습니다.

for (i in myArray) {
    console.log(myArray[i]);
}

그러나 for모든 경우에 기존 루프 와 동일하게 작동하지 않으므로 고려해야 할 잠재적 부작용이 있으므로주의해서 사용해야합니다. 배열 반복과 함께 "for ... in"을 사용하는 것이 좋지 않은 이유를 참조하십시오 .자세한 사항은.

에 대한 대안으로 for...in현재도 있습니다 for...of. 다음 예제는 for...of루프와 루프 의 차이점을 보여줍니다 for...in.

var myArray = [3, 5, 7];
myArray.foo = "hello";

for (var i in myArray) {
  console.log(i); // logs 0, 1, 2, "foo"
}

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

또한 Internet Explorer를 지원하지 않는 버전 for...of( Edge 12+ 는 지원 하지 않음) 이상 이며 for...inInternet Explorer 10 이상 이 필요하다는 점을 고려해야합니다 .


Array.prototype.forEach()

for-loops 의 대안 Array.prototype.forEach()은 다음 구문을 사용하는 것입니다.

myArray.forEach(function(value, key, myArray) {
    console.log(value);
});

Array.prototype.forEach() Internet Explorer 9 이상뿐만 아니라 모든 최신 브라우저에서 지원됩니다.


도서관

마지막으로 많은 유틸리티 라이브러리에도 고유 한 foreach변형이 있습니다. 가장 인기있는 세 가지 AFAIK는 다음과 같습니다.

jQuery.each()에서 jQuery를 :

$.each(myArray, function(key, value) {
    console.log(value);
});

_.each()Underscore.js :

_.each(myArray, function(value, key, myArray) {
    console.log(value);
});

_.forEach()Lodash.js :

_.forEach(myArray, function(value, key) {
    console.log(value);
});

68

while 루프를 사용하십시오 ...

var i=0, item, items = ['one','two','three'];
while(item = items[i++]){
    console.log(item);
}

로그 : '1', 'two', 'three'

역순의 경우 훨씬 효율적인 루프

var items = ['one','two','three'], i = items.length;
while(i--){
    console.log(items[i]);
}

로그 : 'three', 'two', 'one'

아니면 클래식 for루프

var items = ['one','two','three']
for(var i=0, l = items.length; i < l; i++){
    console.log(items[i]);
}

로그 : '1', 'two', 'three'

참조 : http://www.sitepoint.com/google-closure-how-not-to-write-javascript/


21
배열 요소 중 하나라도 거짓이면 "while"구문의 첫 번째 예가 작동하지 않습니다.
Chris Cooper

2
... 그리고이 while 루프는 for : var (var i = 0, item; item = items [i]; i ++)와 동일합니다. 이는 사전에 색인 및 항목 변수를 선언 할 필요가 없습니다 ...
Stijn de Witt


39

당신이 원하는 경우 간결한 방법은 빠른 루프를 작성 하고 당신은 역으로 반복 할 수있다

for (var i=myArray.length;i--;){
  var item=myArray[i];
}

이것은 (유사 길이 캐싱의 이익을 가지고 for (var i=0, len=myArray.length; i<len; ++i)와는 달리을 for (var i=0; i<myArray.length; ++i)입력 할 수 이하의 문자를하면서 참조).

반복하는 동안 DOM에서 항목을 제거 할 계획 인 라이브 NodeList를 반복하는 경우와 같이 역순으로 반복해야하는 경우가 있습니다 .


16
독창적 인 것을 얻지 못하는 사람들을 위해 : i-식이 먼저 평가되고 루프가 잘못되지 않을 때 루프가 계속되도록 허용합니다 ... 그 후 카운터가 감소합니다. Javascript에서 0이 거짓 값이므로 i가 0이되면 루프에서 빠져 나옵니다.
Stijn de Witt

5
거짓? 당신은 거짓을 의미합니다. 혼동을 피하기 위해 모두 적절한 용어를 고수합시다.)
danwellman

4
나는 전문가라고 생각하는 사람들이 허위라는 용어를 사용하는 것을 보았습니다. 그들에게 충분하다면 나에게 충분합니다. 또한 실제로 논 토픽이며 설명 / 통찰력을 추가하는 내 의견은 0 upvotes를 얻지 만 내 의견의 용어에 대한 nitpicks는 4를 얻습니다. 아아 우선 순위의 문제입니다.
Stijn de Witt

"길이 잡기"? 길이는 배열에 정수로 저장되며 액세스 할 때마다 측정되지 않습니다. 길이 값을 다른 변수에 복사하면 이점이 없습니다.
Mouscellaneous

1
@Mouscellaneous 요즘 확실히 없습니다; 지난 몇 년 동안 자바 스크립트 배열의 길이를 캐싱하는 것 (구현 전반에 걸쳐 도달하는 대신)은 퍼포먼스 향상 (미세 최적화시)이었습니다. 예를 들어, for (var i=0,len=array.length;i<len;++i)일반적이고 합리적인 루프를 작성했습니다.
Phrogz

36

JavaScript에서 함수형 프로그래밍 방식으로 배열을 반복하는 일부 사용 사례 :

1. 그냥 배열을 반복

const myArray = [{x:100}, {x:200}, {x:300}];

myArray.forEach((element, index, array) => {
    console.log(element.x); // 100, 200, 300
    console.log(index); // 0, 1, 2
    console.log(array); // same myArray object 3 times
});

참고 : Array.prototype.forEach ()는 입력 매개 변수로받는 함수가 값을 리턴하지 않으므로 순수한 함수로 간주 될 수 없으므로 엄밀히 말하면 기능적인 방식은 아닙니다.

2. 배열의 요소 중 하나라도 테스트를 통과했는지 확인

const people = [
    {name: 'John', age: 23}, 
    {name: 'Andrew', age: 3}, 
    {name: 'Peter', age: 8}, 
    {name: 'Hanna', age: 14}, 
    {name: 'Adam', age: 37}];

const anyAdult = people.some(person => person.age >= 18);
console.log(anyAdult); // true

3. 새로운 배열로 변환

const myArray = [{x:100}, {x:200}, {x:300}];

const newArray= myArray.map(element => element.x);
console.log(newArray); // [100, 200, 300]

참고 : map () 메서드는 호출 배열의 모든 요소에서 제공된 함수를 호출 한 결과로 새 배열을 만듭니다.

4. 특정 재산을 요약하고 평균을 계산

const myArray = [{x:100}, {x:200}, {x:300}];

const sum = myArray.map(element => element.x).reduce((a, b) => a + b, 0);
console.log(sum); // 600 = 0 + 100 + 200 + 300

const average = sum / myArray.length;
console.log(average); // 200

5. 원본을 기반으로하지만 수정하지 않고 새 어레이를 만듭니다.

const myArray = [{x:100}, {x:200}, {x:300}];

const newArray= myArray.map(element => {
    return {
        ...element,
        x: element.x * 2
    };
});

console.log(myArray); // [100, 200, 300]
console.log(newArray); // [200, 400, 600]

6. 각 카테고리의 수를 센다

const people = [
    {name: 'John', group: 'A'}, 
    {name: 'Andrew', group: 'C'}, 
    {name: 'Peter', group: 'A'}, 
    {name: 'James', group: 'B'}, 
    {name: 'Hanna', group: 'A'}, 
    {name: 'Adam', group: 'B'}];

const groupInfo = people.reduce((groups, person) => {
    const {A = 0, B = 0, C = 0} = groups;
    if (person.group === 'A') {
        return {...groups, A: A + 1};
    } else if (person.group === 'B') {
        return {...groups, B: B + 1};
    } else {
        return {...groups, C: C + 1};
    }
}, {});

console.log(groupInfo); // {A: 3, C: 1, B: 2}

7. 특정 기준에 따라 어레이의 서브 세트 검색

const myArray = [{x:100}, {x:200}, {x:300}];

const newArray = myArray.filter(element => element.x > 250);
console.log(newArray); // [{x:300}] 

참고 : filter () 메서드는 제공된 함수로 구현 된 테스트를 통과하는 모든 요소를 ​​사용하여 새 배열을 만듭니다.

8. 배열 정렬

const people = [
  { name: "John", age: 21 },
  { name: "Peter", age: 31 },
  { name: "Andrew", age: 29 },
  { name: "Thomas", age: 25 }
];

let sortByAge = people.sort(function (p1, p2) {
  return p1.age - p2.age;
});

console.log(sortByAge);

여기에 이미지 설명을 입력하십시오

9. 배열에서 요소 찾기

const people = [ {name: "john", age:23},
                {name: "john", age:43},
                {name: "jim", age:101},
                {name: "bob", age:67} ];

const john = people.find(person => person.name === 'john');
console.log(john);

여기에 이미지 설명을 입력하십시오

Array.prototype.find () 메서드는 제공된 테스트 함수를 만족하는 배열의 첫 번째 요소 값을 반환합니다.

참고 문헌


30

루프에 암시 적 범위가 거의없고 추가 변수를 사용하지 않는 경우에 수행 할 수있는 방법이 있습니다.

var i = 0,
     item;

// note this is weak to sparse arrays or falsey values
for ( ; item = myStringArray[i++] ; ){ 
    item; // This is the string at the index.
}

또는 정말로 ID를 얻고 정말로 고전적인 for루프를 원한다면 :

var i = 0,
    len = myStringArray.length; // cache the length

for ( ; i < len ; i++ ){
    myStringArray[i]; // Don't use this if you plan on changing the length of the array
}

현대 브라우저 모든 지원 반복자 방법 forEach, map, reduce, filter그리고 다른 방법의 호스트 배열 프로토 타입 .


3
코드가 충분한 횟수만큼 호출되면 일부 인터프리터 (예 : V8)는 배열의 길이를 자동으로 캐시하고 길이가 루프에 의해 수정되지 않은 것을 감지합니다.
Phrogz 2016 년

@Phrogz 정보 덕분에 VM이 수행 할 수있는 최적화가 많이 있다는 것이 사실이지만, 오래된 브라우저에는이 기능이 없으므로 너무 저렴하기 때문에 최적화하는 것이 가장 좋습니다.
Gabriel

1
@ 가브리엘 : 왜? 길이를 캐싱하지 않는 것이 실제로 성능 병목임을 나타내는 실제 예를 제공하십시오. 나는 '조기 최적화는 모든 악의 뿌리'접근 방식을 따릅니다. 나는 일단 그것을 만나면 실제로 문제를
일으키는

1
@ StijndeWitt imo 그것은 문체 문제입니다. 솔직히 더 이상 for 루프를 사용하지 않고 대신 _.each, _.map 등과 같은 것들에 밑줄을 사용하여 이러한 작업을 수행합니다. 이와 같은 루프를 작성할 때 모든 변수 선언이 내 함수의 맨 위에 한곳에 있도록 길이를 주로 캐시했습니다. 이와 관련하여 내 조언을 따르는 것은 실제 응용 프로그램에 중요하지 않습니다. 조기 최적화는 매우 나쁘지만 최적화가 문체 결정으로 인해 발생하는 경우 실제로 중요하지 않다고 생각합니다.
Gabriel

1
@Gabriel JavaScript가 이미 배열에서 map 함수를 지원한다고 믿기 때문에 추가 라이브러리를 추가 할 필요가 없습니다.
Noz

28

JavaScript에서 배열을 반복하는 다양한 방법이 있습니다.

일반 루프 :

var i;
for (i = 0; i < substr.length; ++i) {
    // Do something with `substr[i]`
}

ES5의 각 기능 :

substr.forEach(function(item) {
    // Do something with `item`
});

jQuery.each :

jQuery.each(substr, function(index, item) {
    // Do something with `item` (or `this` is also `item` if you like)
});

봐 가지고 자세한 정보를 또는 당신은 또한 확인할 수 있습니다 MDN을 자바 스크립트에서 배열을 통해 반복 및 jQuery를 확인 사용하는 각각의 jQuery를 .


27

underscore.js 를 사용하는 것이 좋습니다. 라이브러리를 . 배열 / 컬렉션을 반복하는 데 사용할 수있는 다양한 기능을 제공합니다.

예를 들어 :

_.each([1, 2, 3], function(num){ alert(num); });
=> alerts each number in turn...

7
이 질문에 대한 새로운 발견 자들에게는 Underscore의 영적 후계자 인 Lo-Dash 를 지적하고 싶습니다 .
Mark Reed

3
ECMA-262 가 추가 된 underscore경우 왜 사용 합니까? 기본 코드는 항상 좋습니다. forEach
Walter Chapilliquen-wZVanG 2016 년

27

배열 루프 :

for(var i = 0; i < things.length; i++){
    var thing = things[i];
    console.log(thing);
}

객체 루프 :

for(var prop in obj){
    var propValue = obj[prop];
    console.log(propValue);
}

27

, 루프를 사용하여 JavaScript에서 동일한 작업을 수행 할 수 있지만 이에 국한되지는 않지만 JavaScript에서 배열을 반복하는 방법에는 여러 가지가 있습니다. 이 배열이 아래에 있고 그 위에 루프를 만들고 싶다고 상상해보십시오.

var arr = [1, 2, 3, 4, 5];

솔루션은 다음과 같습니다.

1) For 루프

for루프는 자바 스크립트 배열을 통해 반복하는 일반적인 방법은 없지만, 더 큰 배열을위한 가장 빠른 솔루션으로 간주 :

for (var i=0, l=arr.length; i<l; i++) {
  console.log(arr[i]);
}

2) While 루프

while 루프는 긴 배열을 반복하는 가장 빠른 방법으로 간주되지만 일반적으로 JavaScript 코드에서 덜 사용됩니다.

let i=0;

while (arr.length>i) {
    console.log(arr[i]);
    i++;
}

3)
A do whilewhile아래와 같이 구문 차이 가있는 것과 동일한 일을하는 동안 수행하십시오 .

let i=0;
do {
  console.log(arr[i]);
  i++;
}
while (arr.length>i);

이것이 JavaScript 루프를 수행하는 주요 방법이지만 몇 가지 방법이 더 있습니다.

또한 for inJavaScript에서 객체를 반복 하기 위해 루프를 사용합니다 .

또한보고 map(), filter(), reduce()자바 스크립트의 배열 등의 기능을한다. 그들은 빠르고 더 나은 사용하는 것보다 많은 일을 할 수 whilefor.

JavaScript의 배열에 대한 비동기 함수에 대해 더 배우고 싶다면 좋은 기사입니다.

함수형 프로그래밍은 요즘 개발 세계에서 대폭적인 발전을 이루었습니다. 그리고 정당한 이유 : 기능적 기술을 사용하면 한눈에 이해하고 리팩토링하고 테스트 할 수있는보다 선언적인 코드를 작성할 수 있습니다.

함수형 프로그래밍의 초석 중 하나는 목록 및 목록 작업의 특수한 사용입니다. 그리고 그 것들은 정확히 소리와 같습니다 : 일의 배열, 그리고 당신이하는 일. 그러나 기능적 사고 방식은 예상과 약간 다르게 처리합니다.

이 기사에서는 내가지도, 필터링 및 축소와 같은 "큰 세 가지"목록 작업이라고 부르는 것을 자세히 살펴 보겠습니다. 이 세 가지 기능을 머리에 감는 것은 깨끗한 기능 코드를 작성할 수있는 중요한 단계이며 기능성 및 반응 형 프로그래밍의 강력한 기술에 대한 문을 열어줍니다.

또한 for 루프를 다시 작성할 필요가 없습니다.

>> 자세히보기 여기 :


배열을 반복 할 때 for 루프와 while 루프 전에 성능 차이가 실제로 있습니까? 나는 그 차이가 주로 문법적이라는 인상을 받았다
Shea

24

배열 반복에 사용 가능한 여러 메커니즘의 성능 측면에 관심이있는 사람은 다음 JSPerf 테스트를 준비했습니다.

https://jsperf.com/fastest-array-iterator

성과 결과

결과 :

전통적인 for()반복자는 특히 배열 길이 캐시 와 함께 사용될 때 가장 빠른 방법 입니다.

let arr = [1,2,3,4,5];

for(let i=0, size=arr.length; i<size; i++){
    // Do something
}

그만큼 Array.prototype.forEach()Array.prototype.map()방법은 아마의 결과로, 가장 느린 근사치 함수 호출 오버 헤드 .


i = i +1대신 사용 하는 것이 좋습니다i++
DarckBlezzer

2
개선 될 수 있습니다 : i ++ 대신 ++ i를 사용하십시오. 이는 임시 객체를 피합니다. 따라서 메모리 사용량과 CPU 시간이 줄어 듭니다 (할당 필요 없음)!
PowerStat

@PowerStat 당신은 그것에 대한 링크 또는 참조를 제공 할 수 있습니까? 나는 그것에 대해 들어 본 적이 없다, 재미있는 소리 ...
colxi

1
@colxi 흥미로운 것들을 위해 Herb Sutter와 Scott Meyers의 하드 코어 C ++ 자료를 읽어야합니다. ++ i vs i ++의 내용은 뛰어난 C ++ : 47 공학 퍼즐, 프로그래밍 문제 및 솔루션이라는 책에서 비롯 되었습니다. gotw.ca 에서도 찾을 수 있지만 모든 프로그래밍 언어에서 입증 될 수 있습니다.
PowerStat

21

jQuery 라이브러리를 사용하는 경우 http://api.jquery.com/jQuery.each/ 사용을 고려하십시오.

설명서에서 :

jQuery.each( collection, callback(indexInArray, valueOfElement) )

반환 값 : Object

설명 : 일반 반복자 함수로, 객체와 배열을 완벽하게 반복하는 데 사용할 수 있습니다. length 속성 (예 : 함수의 arguments 객체)이있는 배열 및 배열 유사 객체는 0에서 길이 -1까지의 숫자 인덱스로 반복됩니다. 다른 객체는 명명 된 속성을 통해 반복됩니다.

$.each()함수 $(selector).each()는와 동일하지 않으며 독점적으로 jQuery 객체를 반복하는 데 사용됩니다. 이 $.each() 함수는 맵 (JavaScript 객체)이든 배열이든 모든 컬렉션을 반복하는 데 사용할 수 있습니다. 배열의 경우 콜백은 매번 배열 인덱스와 해당 배열 값을 전달받습니다. ( this키워드를 통해 값에 액세스 할 수도 있지만 Javascript는 thisObject이 단순 문자열 또는 숫자 값인 경우에도 항상 값을 랩핑합니다 .)이 메소드는 반복 된 오브젝트의 첫 번째 인수를 리턴합니다.


9
모든 것을위한 jQuery?
예외

6
예외적으로 동의했습니다. 추가 종속성의 영향을 과소 평가하지 마십시오. 어쨌든 jQuery를 이미 많이 사용하는 코드를 제외하고는 이것에 대해 조언 할 것입니다.
Stijn de Witt

2
업데이트 : 요즘 Array.forEach 를 사용 하여 기본 배열과 거의 동일한 효과를 얻을 수 있습니다 .
Stijn de Witt

20

나는 개인적으로 가장 좋아하는이 변형을 보지 못했습니다.

주어진 배열 :

var someArray = ["some", "example", "array"];

length 속성에 액세스하지 않고도 루프를 반복 할 수 있습니다.

for (var i=0, item; item=someArray[i]; i++) {
  // item is "some", then "example", then "array"
  // i is the index of item in the array
  alert("someArray[" + i + "]: " + item);
}

이것을 보여주는 JsFiddle을 참조하십시오 : http://jsfiddle.net/prvzk/

이것은 단지입니다 배열 작동 하지 스파 스. 실제로 배열의 각 인덱스에 값이 있음을 의미합니다. 그러나 실제로는 JavaScript에서 스파 스 배열을 거의 사용하지 않는다는 것을 알았습니다 ... 이러한 경우 일반적으로 객체를 맵 / 해시 테이블로 사용하는 것이 훨씬 쉽습니다. 희소 배열이 있고 0 .. length-1을 반복하려면 for (var i = 0; i <someArray.length; ++ i) 구문이 필요하지만 여전히 if루프 내부가 필요합니다 현재 인덱스의 요소가 실제로 정의되어 있는지 확인합니다.

또한 CMS가 아래 주석에서 언급했듯이 허위 값이 포함되지 않은 배열에서만 사용할 수 있습니다. 예제의 문자열 배열은 작동하지만 빈 문자열이나 0 또는 NaN 등의 숫자가 있으면 루프가 조기에 끊어집니다. 다시 말하지만 실제로 이것은 결코 문제가되지 않지만 명심해야 할 것이 있습니다.이를 사용하기 전에이 루프를 생각하면됩니다.

이 루프에서 내가 좋아하는 것은 :

  • 쓰기가 짧다
  • 길이 속성에 액세스 할 필요가 없습니다 (캐시 만 허용).
  • 액세스 할 항목은 선택한 이름으로 루프 본문 내에서 자동으로 정의됩니다.
  • 리스트 / 스택과 같은 배열을 사용하기 위해 array.push 및 array.splice와 매우 자연스럽게 결합

이것이 작동하는 이유는 배열 사양이 인덱스> = 배열의 길이에서 항목을 읽을 때 정의되지 않은 값을 반환해야하기 때문입니다. 이러한 위치에 쓰면 실제로 길이가 업데이트됩니다.

나 에게이 구조는 내가 좋아하는 Java 5 구문을 가장 가깝게 모방합니다.

for (String item : someArray) {
}

... 루프 내부의 현재 색인에 대해 알고 있다는 추가 이점


13
이 방법으로 루프를 즉시 중지 할 것을 공지 사항 그것이 발견 falsey 값을 같은 빈 문자열로,, 0, false, NaN, null또는 undefined, 심지어 이전 i에 도달 길이, 예를 들면 : jsfiddle.net/prvzk/1
CMS

3
루프 조건은 다음과 같습니다 (item=someArray[i]) !== undefined.
daniel1426

18

프로토 타입을 포함하지 않고 자신의 객체 속성 만 반복하는 방법이 있습니다.

for (var i in array) if (array.hasOwnProperty(i)) {
    // Do something with array[i]
}

그러나 여전히 사용자 정의 속성을 반복합니다.

JavaScript에서는 배열을 포함하여 모든 사용자 정의 특성을 모든 오브젝트에 지정할 수 있습니다.

희소 배열을 반복 for (var i = 0; i < array.length; i++) if (i in array)하거나 array.forEachwith를 es5shim사용해야하는 경우.


그리고 어떻게 사용 for (var i in array) if (++i)합니까?
Daniel Sokolowski

15

JavaScript에서 몇 가지 방법이 있습니다. 처음 두 예제는 JavaScript 샘플입니다. 세 번째는 자바 스크립트 라이브러리, 즉 .each()함수 를 사용하는 jQuery를 사용 합니다.

var myStringArray = ["hello", "World"];
for(var i in myStringArray) {
  alert(myStringArray[i]);
}

var myStringArray = ["hello", "World"];
for (var i=0; i < myStringArray.length; i++) {
  alert(myStringArray[i]);
}

var myStringArray = ["hello", "World"];
$.each(myStringArray, function(index, value){
  alert(value);
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>


for...in배열과 유사한 객체의 경우 피해야합니다
brk

15

가장 우아하고 빠른 방법

var arr = [1, 2, 3, 1023, 1024];
for (var value; value = arr.pop();) {
    value + 1
}

http://jsperf.com/native-loop-performance/8


내가 잘못했기 때문에 수정 됨


100000 개 항목의 배열을 반복하는 방법을 비교하고 매번 새로운 값으로 최소한의 작업을 수행합니다.

예비:

<script src="//code.jquery.com/jquery-2.1.0.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.6.0/underscore-min.js"></script>
<script>
    Benchmark.prototype.setup = function() {
        // Fake function with minimal action on the value
        var tmp = 0;
        var process = function(value) {
            tmp = value; // Hold a reference to the variable (prevent engine optimisation?)
        };

        // Declare the test Array
        var arr = [];
        for (var i = 0; i < 100000; i++)
            arr[i] = i;
    };
</script>

테스트 :

<a href="http://jsperf.com/native-loop-performance/16" 
   title="http://jsperf.com/native-loop-performance/16"
><img src="http://i.imgur.com/YTrO68E.png" title="Hosted by imgur.com" /></a>

이 루프는 배열의 항목 순서를 따르지 않는 것 같습니다.
Deniz Ozger

내 시험이 틀렸다. 이제 모든 루프를 표시하는 것이 정확합니다. jsperf.com/native-loop-performance/16
molokoloco

@bergi가 맞습니다. 이 루프는 배열을 반복하면서 배열을 지 웁니다. 대부분의 경우 원하는 것이 아닙니다.
Stijn de Witt

4
잘못된 아이템을 깰 수 있습니다.
njzk2

12

최적화 된 방법은 배열 길이를 캐시하고 단일 var 키워드로 모든 변수를 초기화하는 단일 var 패턴을 사용하는 것입니다.

var i, max, myStringArray = ["Hello","World"];
for (i = 0, max = myStringArray.length; i < max; i++) {
    alert(myStringArray[i]);
   //Do something
}

반복 루프를 시도하는 것보다 반복 순서가 중요하지 않은 경우 오버 헤드 조건 테스트를 줄이고 하나의 명령문으로 감소하므로 가장 빠릅니다.

var i,myStringArray = ["item1","item2"];
for (i =  myStringArray.length; i--) {
    alert(myStringArray[i]);
}

while 루프를 사용하는 것이 더 좋고 깨끗합니다.

var myStringArray = ["item1","item2"],i = myStringArray.length;
while(i--) {
   // do something with fruits[i]
}

12

JavaScript에는 배열을 반복하는 솔루션이 너무 많습니다.

아래 코드는 인기있는 코드입니다

/** Declare inputs */
const items = ['Hello', 'World']

/** Solution 1. Simple for */
console.log('solution 1. simple for')

for (let i = 0; i < items.length; i++) {
  console.log(items[i])
}

console.log()
console.log()

/** Solution 2. Simple while */
console.log('solution 2. simple while')

let i = 0
while (i < items.length) {
  console.log(items[i++])
}

console.log()
console.log()

/** Solution 3. forEach*/
console.log('solution 3. forEach')

items.forEach(item => {
  console.log(item)
})

console.log()
console.log()

/** Solution 4. for-of*/
console.log('solution 4. for-of')

for (const item of items) {
  console.log(item)
}

console.log()
console.log()


12

jQuery를 사용하려면 설명서에 좋은 예가 있습니다.

 $.each([ 52, 97 ], function( index, value ) {
      alert( index + ": " + value );
 });

12

제 생각에는 가장 좋은 방법은 Array.forEach 함수를 사용하는 것입니다. 당신이 그것을 사용할 수 없다면 나는 MDN에서 polyfill을 얻는 것이 좋습니다. 사용 가능하게하려면 JavaScript에서 배열을 반복하는 가장 안전한 방법입니다.

Array.prototype.forEach ()

다른 사람들이 제안했듯이 이것은 거의 항상 원하는 것입니다.

var numbers = [1,11,22,33,44,55,66,77,88,99,111];
var sum = 0;
numbers.forEach(function(n){
  sum += n;
});

이렇게하면 배열 처리 범위에 필요한 모든 항목이 해당 범위 내에 유지되고 객체 속성 및 기타 멤버가 아닌 배열의 값만 처리하게됩니다 for ...

일반 C 스타일 사용 for 루프를 대부분의 경우 작동합니다. 루프 내의 모든 것이 범위를 나머지 프로그램과 공유한다는 점을 기억하는 것이 중요합니다. {}는 새 범위를 만들지 않습니다.

그 후:

var sum = 0;
var numbers = [1,11,22,33,44,55,66,77,88,99,111];

for(var i = 0; i<numbers.length; ++i){
  sum += numbers[i];
}

alert(i);

"11"을 출력합니다-원하는 것이거나 아닐 수도 있습니다.

작동하는 jsFiddle 예제 : https://jsfiddle.net/workingClassHacker/pxpv2dh5/7/


10

100 % 동일하지는 않지만 비슷합니다.

   var myStringArray = ['Hello', 'World']; // array uses [] not {}
    for (var i in myStringArray) {
        console.log(i + ' -> ' + myStringArray[i]); // i is the index/key, not the item
    }


1
이것은 프로토 타입 멤버 변수가 for에 의해 잡힐 것이라는 점에서 배열 객체를 사용할 때와 비슷한 문제에 대해 발생하는 것으로 보입니다.
Kzqai

9

예를 들어 Firefox 콘솔에서 사용했습니다.

[].forEach.call(document.getElementsByTagName('pre'), function(e){ 
   console.log(e);
})

9
var x = [4, 5, 6];
for (i = 0, j = x[i]; i < x.length; j = x[++i]) {
    console.log(i,j);
}

훨씬 더 깨끗한 ...


에 비해 매우 깨끗하지 않습니다 z.forEach(j => console.log(j));.
사파이어

9

짧은 대답 : 예. 당신은 이것을 할 수 있습니다 :

var myArray = ["element1", "element2", "element3", "element4"];

for (i = 0; i < myArray.length; i++) {
  console.log(myArray[i]);
}

브라우저 콘솔에서 "element1", "element2"등과 같은 인쇄 된 것을 볼 수 있습니다.


9

다음 중 하나를 사용할 수 있습니다 Array.prototype.forEach(...).

var arr = ["apple", "banana", "cherry", "mango"];
arr.forEach((item, index)=>{
   //Some code...
});

또는 Array.prototype.map(...):

var arr = ["apple", "banana", "cherry", "mango"];
arr.map((item, index)=>{
   //Some code...
});

또는 이전에 언급 한 jquery 또는 for 루프 방식.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.