JavaScript를 사용하여 배열의 모든 항목을 반복하는 방법은 무엇입니까?
나는 이것이 다음과 같다고 생각했다.
forEach(instance in theArray)theArray내 배열은 어디에 있지만 이것은 잘못된 것 같습니다.
답변
TL; DR
- for-in안전 장치와 함께 사용하거나 그것이 왜 당신을 물릴 수 있는지 알지 못한다면 사용 하지 마십시오 .
- 
가장 좋은 건은 보통 
그러나 거기 많이 읽어, 탐험 더 …
JavaScript에는 배열 및 배열과 유사한 객체를 반복하는 강력한 의미가 있습니다. 대답은 두 가지 부분으로 나뉩니다. 순수 배열 옵션과 객체, 다른 반복 가능한 객체 (ES2015 +), DOM 컬렉션 등과 같이 배열 과 비슷한 항목에 대한 옵션 arguments.
당신이 ES2015 옵션을 사용할 수있는 나는 빨리 알게 될 것이다 지금 에 의해, 심지어 ES5 엔진에 transpiling ES5에 ES2015을. 자세한 내용은 “ES2015 transpiling”/ “ES6 transpiling”을 검색하십시오.
자, 우리의 옵션을 보자.
실제 배열의 경우
당신은 세 가지 옵션이 있습니다 인 ECMAScript 5 ( “ES5을”) 버전은 가장 광범위 순간에 지원, 2 개의 더 추가 ECMAScript를 2015 ( “ES2015”, “ES6”) :
- 사용 forEach및 관련 (ES5 +)
- 간단한 for루프를 사용하십시오
- 올바르게 사용for-in
- 사용 for-of(이터레이터를 암시 적으로 사용) (ES2015 +)
- 반복자를 명시 적으로 사용하십시오 (ES2015 +)
세부:
1. 사용 forEach및 관련
ArrayES5에 의해 추가 된 기능 (직접 또는 폴리 필 사용)에 액세스 할 수있는 모호한 현대 환경 (IE8이 아님)에서 forEach( spec| MDN)를 사용할 수 있습니다 .
var a = ["a", "b", "c"];
a.forEach(function(entry) {
    console.log(entry);
});forEach콜백 함수 및 선택적으로 this해당 콜백을 호출 할 때 사용할 값 (위에서 사용되지 않음)을 수락합니다 . 배열의 각 항목에 대해 콜백이 호출되어 희소 배열의 존재하지 않는 항목은 건너 뜁니다. 위의 인수 하나만 사용했지만 콜백은 세 가지로 호출됩니다. 각 항목의 값, 해당 항목의 색인 및 반복하는 배열에 대한 참조 ).
IE8 (2016 년 9 월이 글을 쓰는 시점에 NetApps가 시장 점유율을 4 % 이상으로 표시)과 같은 오래된 브라우저를 지원하지 않는 한, forEachshim없이 범용 웹 페이지에서 행복하게 사용할 수 있습니다 . 더 이상 사용되지 않는 브라우저를 지원해야하는 경우에는 shimming / polyfilling forEach을 쉽게 수행 할 수 있습니다 (여러 옵션의 경우 “es5 shim”검색).
forEach 반복 함수에 인수로 제공되므로 포함 범위에서 인덱싱 및 값 변수를 선언 할 필요가 없다는 장점이 있습니다.
각 배열 항목에 대한 함수 호출의 런타임 비용이 걱정된다면 걱정하지 마십시오. 세부 사항 .
또한 forEach“모두 반복”기능이지만 ES5는 다음과 같은 몇 가지 유용한 “어레이를 통해 작업하고 작업을 수행”기능을 정의했습니다.
- every(콜백이 처음 반환 될 때 루핑이 중지- false되거나 잘못된 것)
- some(콜백이 처음 반환 될 때 루핑이 중지- true되거나 사실이 아닙니다)
- filter(필터 함수가 리턴하는 요소를 포함하는 새로운 배열을 작성하고 리턴하는 요소는- true생략 함- false)
- map(콜백에서 반환 한 값으로 새 배열을 만듭니다)
- reduce(콜백을 반복해서 호출하여 이전 값을 전달하여 값을 작성합니다. 세부 사항에 대한 스펙을 참조하십시오.
- reduceRight(와- reduce같지만 오름차순이 아닌 내림차순으로 작동)
2. 간단한 for루프를 사용하십시오
때로는 오래된 방법이 가장 좋습니다.
var index;
var a = ["a", "b", "c"];
for (index = 0; index < a.length; ++index) {
    console.log(a[index]);
}배열의 길이가 루프 동안 변경되지 않습니다, 그것은 (가능성) 성능에 민감한 코드의 경우, 앞까지 길이를 잡아 약간 더 복잡한 버전은 수 있습니다 작은 비트 빠른 :
var index, len;
var a = ["a", "b", "c"];
for (index = 0, len = a.length; index < len; ++index) {
    console.log(a[index]);
}그리고 / 또는 뒤로 계산 :
var index;
var a = ["a", "b", "c"];
for (index = a.length - 1; index >= 0; --index) {
    console.log(a[index]);
}그러나 최신 JavaScript 엔진을 사용하면 마지막 주스를 피할 필요가 거의 없습니다.
ES2015 이상에서는 인덱스 및 값 변수를 for루프에 로컬로 만들 수 있습니다 .
let a = ["a", "b", "c"];
for (let index = 0; index < a.length; ++index) {
    let value = a[index];
    console.log(index, value);
}
//console.log(index);   // would cause "ReferenceError: index is not defined"
//console.log(value);   // would cause "ReferenceError: value is not defined"
그리고 그렇게 할 때, 각 루프 반복에 대해 다시 생성 될 value뿐만 아니라 index다시 생성되므로 루프 본문에서 생성 된 클로저 는 해당 반복에 대해 생성 된 index(및 value)에 대한 참조를 유지합니다 .
let divs = document.querySelectorAll("div");
for (let index = 0; index < divs.length; ++index) {
    divs[index].addEventListener('click', e => {
        console.log("Index is: " + index);
    });
}
5 개의 div가있는 경우 첫 번째를 클릭하면 “Index is : 0″이 표시되고 마지막을 클릭하면 “Index is : 4″가 표시됩니다. 대신 대신 사용하면 작동 하지 않습니다 .varlet
3. 올바르게 사용for-in 
사람들에게 당신에게 사용하라고 말하게 할 것 입니다 . for-in그러나 그것이 아닙니다for-in . 배열의 인덱스가 아닌 객체for-in 의 열거 가능한 속성을 반복합니다 . ES2015 (ES6)에서도 주문이 보장 되지 않습니다. ES2015 +는 개체 속성에 순서를 정의하지 않습니다 (통해 [[OwnPropertyKeys]], [[Enumerate]]그리고 그것들을 사용하는 것을 좋아 Object.getOwnPropertyKeys), 그러나 그 정의하지 않았다 for-in순서를 따를 것입니다; 그러나 ES2020은 그렇게했다. ( 이 다른 답변에 대한 자세한 내용 )
for-in배열에 대한 유일한 실제 사용 사례 는 다음과 같습니다.
- 그것은이다 스파 스 배열 과 대규모 , 그 격차를 나
- 요소가 아닌 속성을 사용하고 있으며 루프에 포함하려는 경우
첫 번째 예만 살펴보기 : for-in적절한 보호 조치를 사용하는 경우 희소 배열 요소를 방문하는 데 사용할 수 있습니다 .
// `a` is a sparse array
var key;
var a = [];
a[0] = "a";
a[10] = "b";
a[10000] = "c";
for (key in a) {
    if (a.hasOwnProperty(key)  &&        // These checks are
        /^0$|^[1-9]\d*$/.test(key) &&    // explained
        key <= 4294967294                // below
        ) {
        console.log(a[key]);
    }
}세 가지 확인 사항에 유의하십시오.
- 
객체는 그 이름에 따라 자체 속성을 가지고 있으며 (프로토 타입에서 상속 된 속성이 아님) 
- 
키는 모두 10 진수 (예 : 과학적 표기법이 아닌 일반 문자열 형식)이며 
- 
숫자로 강제 변환 될 때 키의 값은 <= 2 ^ 32-2 (4,294,967,294)입니다. 그 번호는 어디에서 왔습니까? 그것은 사양에서 배열 인덱스의 정의의 일부입니다 . 다른 숫자 (정수가 아닌 숫자, 음수, 2 ^ 32-2보다 큰 숫자)는 배열 인덱스가 아닙니다. 이 2 ^ 32의 이유 – 2 – 즉, 2 ^ 32 이상의 낮은 최대 인덱스 값이다하게 한 배열의 최대 값이고 length가질 수있다. (예를 들어, 배열의 길이는 32 비트 부호없는 정수에 맞습니다.) ( 이전 블로그 테스트에서 내 이전 테스트가 옳지 않다는 의견을 지적한 RobG에게 요청합니다 .)
물론 인라인 코드에서는 그렇게하지 않을 것입니다. 유틸리티 함수를 작성합니다. 혹시:
4. 사용 for-of(이터레이터를 암시 적으로 사용) (ES2015 +)
ES2015는 반복자 를 JavaScript에 추가했습니다 . 반복자를 사용하는 가장 쉬운 방법은 새로운 for-of문장입니다. 다음과 같이 보입니다 :
const a = ["a", "b", "c"];
for (const val of a) {
    console.log(val);
}커버 아래에서 배열에서 반복자 를 가져 와서 루프를 통해 값을 가져옵니다. for-in객체 (배열)에 의해 정의 된 반복자를 사용하고 배열 이 속성이 아닌 항목을 통해 반복되도록 정의하기 때문에 using에 문제가 없습니다 . for-inES5 와 달리 항목을 방문하는 순서는 색인의 숫자 순서입니다.
5. 반복자를 명시 적으로 사용하십시오 (ES2015 +)
때로는 반복자를  명시 적으로 사용하고 싶을 수도 있습니다 . 그것보다 훨씬 복잡하지만 그렇게 할 수도 있습니다 for-of. 다음과 같이 보입니다 :
const a = ["a", "b", "c"];
const it = a.values();
let entry;
while (!(entry = it.next()).done) {
    console.log(entry.value);
}반복자는 사양의 반복자 정의와 일치하는 객체입니다. 그 next방법은 새 반환 결과 객체 당신이 그것을 호출 할 때마다. 결과 객체에는 속성이 있으며 done, 완료 여부를 알려주는 속성 value과 해당 반복 값이 있는 속성 이 있습니다. (있는 done경우 선택 사항 false이며, 원하는 value경우 선택 사항 undefined입니다.)
의 의미 value는 반복자 에 따라 다릅니다. 배열은 반복자를 반환하는 (적어도) 세 가지 함수를 지원합니다.
- values(): 이것은 내가 위에서 사용한 것입니다. 그것은 각각 반복자 반환- value이 반복 배열 항목이다 (- "a",- "b"및- "c"실시 예 이전에).
- keys(): 각각- value이 해당 반복에 대한 키인 반복자를 리턴합니다 (따라서- a위의 경우- "0", 그런- "1"다음- "2").
- entries(): 각각- value이- [key, value]해당 반복 양식의 배열 인 반복자를 리턴합니다 .
배열과 같은 객체
실제 배열 외에도 숫자 이름을 가진 속성과 속성을 가진 배열과 같은 객체가 있습니다 length. NodeList인스턴스, arguments객체 등. 우리는 내용을 어떻게 반복합니까?
배열에 대해 위의 옵션 중 하나를 사용하십시오
위의 배열 접근법 중 적어도 일부, 또는 대부분 또는 전체는 종종 배열 유사 객체에 동일하게 적용됩니다.
- 
사용 forEach및 관련 (ES5 +)다양한 기능들은 Array.prototype“의도적 일반”이며 일반적 통해 객체와 같은 배열에 사용될 수있다Function#call나Function#apply. ( 이 답변 끝에 호스트 제공 객체 에 대한 경고를 참조하십시오. 그러나 드문 문제입니다.)당신이 사용하고자 가정하자 forEachA의Node의childNodes속성입니다. 당신은 이것을 할 것입니다 :Array.prototype.forEach.call(node.childNodes, function(child) { // Do something with `child` });그렇게 많이 할 경우, 함수 참조의 사본을 재사용을 위해 변수로 가져와야 할 수 있습니다. 예를 들면 다음과 같습니다. // (This is all presumably in some scoping function) var forEach = Array.prototype.forEach; // Then later... forEach.call(node.childNodes, function(child) { // Do something with `child` });
- 
간단한 for루프를 사용하십시오분명히 간단한 for루프는 배열과 같은 객체에 적용됩니다.
- 
올바르게 사용 for-infor-in배열과 동일한 보호 장치를 사용하면 배열과 유사한 객체에서도 작동해야합니다. 위의 # 1에 호스트 제공 개체에 대한 경고가 적용될 수 있습니다.
- 
사용 for-of(이터레이터를 암시 적으로 사용) (ES2015 +)for-of객체가 제공 하는 반복자를 사용 합니다 (있는 경우). 여기에는 호스트 제공 객체가 포함됩니다. 예를 들어,NodeListfromquerySelectorAll에 대한 스펙이 반복을 지원하도록 업데이트되었습니다. 의 사양HTMLCollection에서가getElementsByTagName아니었다.
- 
반복자를 명시 적으로 사용하십시오 (ES2015 +) # 4를 참조하십시오. 
진정한 배열 만들기
다른 경우에는 배열과 유사한 객체를 실제 배열로 변환 할 수 있습니다. 그렇게하는 것은 놀라 울 정도로 쉽습니다.
- 
slice배열 의 방법을 사용하십시오slice위에서 언급 한 다른 방법들과 마찬가지로 “의도적으로 일반적”인 배열 의 방법을 사용할 수 있으므로 다음 과 같이 배열과 같은 객체와 함께 사용할 수 있습니다.var trueArray = Array.prototype.slice.call(arrayLikeObject);예를 들어, NodeLista를 실제 배열로 변환하려면 다음과 같이하십시오.var divs = Array.prototype.slice.call(document.querySelectorAll("div"));아래의 호스트 제공 객체에 대한주의 사항을 참조하십시오 . 특히, 이것은 IE8 및 이전 버전에서는 실패하므로 호스트 제공 객체를 this이와 같이 사용할 수 없습니다 .
- 
스프레드 구문 사용 ( ...)이 기능을 지원하는 JavaScript 엔진과 함께 ES2015의 스프레드 구문 을 사용할 수도 있습니다 . 마찬가지로 객체에서 제공 for-of하는 반복자를 사용 합니다 (이전 섹션의 # 4 참조).var trueArray = [...iterableObject];예를 들어, NodeList스프레드 구문을 사용하여 a를 실제 배열로 변환하려는 경우 이것은 매우 간결합니다.var divs = [...document.querySelectorAll("div")];
- 
사용하다 Array.fromArray.from(사양) | (MDN) (ES2015 +, 쉽게 폴리 필됨)은 배열과 유사한 객체로부터 배열을 생성하고, 선택적으로 매핑 기능을 통해 항목을 먼저 전달합니다. 그래서:var divs = Array.from(document.querySelectorAll("div"));또는 주어진 클래스가있는 요소의 태그 이름 배열을 얻으려면 매핑 함수를 사용하십시오. // Arrow function (ES2015): var divs = Array.from(document.querySelectorAll(".some-class"), element => element.tagName); // Standard function (since `Array.from` can be shimmed): var divs = Array.from(document.querySelectorAll(".some-class"), function(element) { return element.tagName; });
호스트 제공 객체에 대한주의 사항
호스트 제공 배열 유사 객체 (DOM 목록 및 JavaScript 엔진이 아닌 브라우저에서 제공하는 기타 Array.prototype기능)와 함께 함수 를 사용하는 경우 대상 환경에서 테스트하여 호스트 제공 객체가 제대로 작동하는지 확인해야합니다. . 대부분은 올바르게 동작 하지만 (지금) 테스트하는 것이 중요합니다. 그 이유는 사용하려는 대부분의 방법이 호스트 제공 객체에 의존하여 추상 작업에 정직한 답변을 제공하기 때문 입니다. 이 글을 쓰는 시점에서 브라우저는이 작업을 훌륭하게 수행하지만 5.1 사양에서는 호스트 제공 객체가 정직하지 않을 수 있습니다. §8.6.2 에 있으며 , 해당 섹션의 시작 부분 근처에 큰 테이블 아래에 여러 단락이 있습니다.Array.prototype[[HasProperty]]
호스트 객체는 달리 명시되지 않는 한 어떤 방식 으로든 이러한 내부 메소드를 구현할 수 있습니다. 예를 들어, 하나의 가능성이 있다는 것입니다
[[Get]]및[[Put]]특정 호스트 객체가 실제로 가져오고 저장하는 속성 값을하지만[[HasProperty]]항상 생성 거짓 .
(ES2015 사양에서 동등한 언어를 찾을 수는 없지만 여전히 그렇습니다.) 다시 말하지만, 현대 브라우저에서 일반적인 호스트 제공 배열과 같은 객체 ( NodeList예 : 예) 는 처리합니다. [[HasProperty]]올바르게하지만 테스트하는 것이 중요합니다.)
답변
참고 :이 답변은 절망적 인 구식입니다. 보다 현대적인 접근 방식 은 배열에서 사용 가능한 방법을 살펴보십시오 . 관심있는 방법은 다음과 같습니다.
- 각각
- 지도
- 필터
- 지퍼
- 줄이다
- …마다
- 약간
JavaScript 에서 배열을 반복하는 표준 방법 은 바닐라 for루프입니다.
var length = arr.length,
    element = null;
for (var i = 0; i < length; i++) {
  element = arr[i];
  // Do something with element
}그러나이 방법은 밀도가 높은 배열이 있고 각 인덱스가 요소에 의해 점유 된 경우에만 유용합니다. 배열이 희소 한 경우이 방법을 사용하면 성능 문제가 발생할 수 있습니다 . 배열에 실제로 존재 하지 않는 많은 인덱스를 반복하기 때문 입니다. 이 경우 for .. in-loop가 더 좋습니다. 그러나for..in -loop가 레거시 브라우저에도 열거 되기 때문에 또는 추가 속성이 enumerable.
에서 ECMAScript를 5 배열 프로토 타입에 foreach는 방법이 될 것입니다,하지만 기존의 브라우저에서 지원되지 않습니다. 일관성있게 사용하려면이를 지원하는 환경 (예 : 서버 측 JavaScript의 경우 Node.js )이 있거나 “폴리 필”을 사용해야합니다. 그러나이 기능에 대한 Polyfill은 사소한 것이며 코드를 읽기 쉽게 만들기 때문에 포함하기에 좋은 polyfill입니다.
답변
jQuery 라이브러리를 사용하는 경우 jQuery.each 를 사용할 수 있습니다 .
$.each(yourArray, function(index, value) {
  // do your stuff here
});편집하다 :
질문에 따라 사용자는 jquery 대신 자바 스크립트로 코드를 원하므로 편집은
var length = yourArray.length;
for (var i = 0; i < length; i++) {
  // Do something with yourArray[i].
}답변
뒤로 루프
역 for 루프는 여기에 언급 할 가치가 있다고 생각합니다 .
for (var i = array.length; i--; ) {
     // process array[i]
}장점 :
- 임시 len변수 를 선언 하거나array.length각 반복에 대해 비교할 필요가 없습니다.이 중 하나는 1 분 동안 최적화 될 수 있습니다.
- DOM에서 형제 를 역순으로 제거하는 것이 일반적으로 더 효율적 입니다. (브라우저는 내부 배열에서 요소를 덜 이동해야합니다.)
- 만약 있다면 배열은 수정 또는 인덱스 후에 반복하면서 전 (예를 들어, 제거 또는 항목을 삽입 array[i]), 그 후 정 루프 위치로 왼쪽으로 이동할 항목을 이동 것이다 I 또는 재 공정 된 I 이었다 번째 항목 오른쪽으로 이동했습니다. 전통적인 for 루프에서는 i 를 처리해야하는 다음 항목을 가리 키도록 업데이트 할 수 있지만 반복 방향을 반대로 바꾸는 것이 더 단순 하고 더 우아한 솔루션 인 경우가 많습니다 .
- 마찬가지로 중첩 된 DOM 요소를 수정하거나 제거 할 때 역으로 처리하면 오류 를 피할 수 있습니다 . 예를 들어, 하위 노드를 처리하기 전에 상위 노드의 innerHTML을 수정하십시오. 자식 노드에 도달하면 DOM에서 분리되어 부모의 innerHTML을 작성할 때 새로 만든 자식으로 대체됩니다.
- 사용 가능한 다른 옵션 중 일부 를 입력하고 읽는 것이 더 짧 습니다 . ES6과 는 잃지 만 .forEach()for ... of
단점 :
- 항목을 역순으로 처리합니다. 결과에서 새 배열을 작성하거나 화면에 물건을 인쇄 하는 경우 원래 순서에 따라 출력이 자연스럽게 바뀝니다 .
- 순서를 유지하기 위해 형제를 첫 번째 자식으로 DOM에 반복적으로 삽입하는 것이 덜 효율적 입니다. (브라우저는 계속해서 일을 올바르게 이동해야합니다.) DOM 노드를 효율적이고 순서대로 만들려면 앞으로 루프하고 정상적으로 추가하십시오 (또한 “문서 조각”을 사용하십시오).
- 리버스 루프는 후배 개발자에게 혼란 을줍니다. (전망에 따라 이점을 고려할 수도 있습니다.)
항상 사용해야합니까?
루프 포워드해야 할 이유가없는 한 일부 개발자 는 기본적으로 역방향 for 루프 를 사용합니다 .
일반적으로 성능 향상은 미미하지만 비명은 다음과 같습니다.
“목록에있는 모든 항목에이 작업을 수행하면 주문에 신경 쓰지 않습니다!”
그러나입니다 실제로 하지 당신이 때 그 경우 구별하기 때문에, 실제로 의도 신뢰할 수있는 표시 할 순서에 대해주의를, 정말 할 필요성을 역으로 루프. 실제로 ECMAScript를 포함하여 대부분의 언어에서 사용할 수 없지만 “예 : 신경 쓰지 않음”의도를 정확하게 표현하기 위해서는 다른 구문이 필요합니다 forEachUnordered().
순서가 중요하지 않고 효율성 이 문제가되는 경우 (게임 또는 애니메이션 엔진의 가장 안쪽 루프에서) 역방향 for 루프를 이동 패턴으로 사용하는 것이 좋습니다. 기존 코드에서 역 for 루프를 보는 것이 반드시 순서와 관련 이 없다는 것을 의미하지는 않습니다 !
forEach ()를 사용하는 것이 좋습니다
일반적으로 선명도와 안전 이 더 중요한 고급 코드의 경우 이전 Array::forEach에는 루핑의 기본 패턴으로 사용 하는 것이 좋습니다 (요즘에는을 선호합니다 for..of). forEach역방향 루프보다 선호하는 이유 는 다음과 같습니다.
- 읽는 것이 더 명확합니다.
- 그것은을 나타냅니다 난 (항상 긴에서 가능 깜짝 숨어있는 블록 내에서 이동하지 않을 for및while루프).
- 폐쇄의 자유 범위를 제공합니다.
- 지역 변수의 누출과 외부 변수와의 우연한 충돌 (및 돌연변이)을 줄입니다.
그런 다음 코드에서 리버스 for 루프를 볼 때 이는 좋은 이유 (위에서 설명한 이유 중 하나)로 반전되었다는 힌트입니다. 그리고 전통적인 순방향 for 루프를 보면 시프트가 발생할 수 있음을 나타낼 수 있습니다.
(의도에 대한 논의가 당신에게 이해가되지 않는다면, 당신과 당신의 코드는 Crockford의 Programming Style & Your Brain 에 대한 강의를 보는 것이 도움이 될 것입니다 .)
이제는 사용하는 것이 더 좋습니다.
바람직한 지 for..of또는 forEach()바람직한 지에 대한 논쟁이 있습니다 .
- 
최대 브라우저 지원을 for..of위해서는 반복자에 대한 폴리 필이 필요하므로 앱 실행 속도가 약간 느려지고 다운로드 크기가 약간 커집니다.
- 
이러한 이유로 (및 사용을 장려 map하고filter), 일부 프런트 엔드 스타일 가이드는 금지for..of완전히!
- 
그러나 위의 문제는 Node.js 응용 프로그램에는 적용되지 않으며 for..of현재 잘 지원되고 있습니다.
- 
그리고 더 이상 내부에서 await작동하지 않습니다forEach(). 이 경우 사용for..of이 가장 명확한 패턴 입니다.
개인적으로, 성능이나 축소가 주요 관심사가되지 않는 한 읽기 쉬운 것처럼 보이는 것을 사용하는 경향이 있습니다. 요즘 그래서 내가 사용하는 것을 선호 for..of대신 forEach(),하지만 난 항상 사용 map또는 filter또는 find또는 some해당되는 경우. (내 동료를 위해 거의 사용하지 않습니다 reduce.)
어떻게 작동합니까?
for (var i = 0; i < array.length; i++) { ... }   // Forwards
for (var i = array.length; i--; )    { ... }   // Reverse당신은 그 통지합니다 i--(우리가 일반적으로 볼 경우 (우리가 일반적으로 비교 참조) 마지막 절은 비어 중간 절입니다 i++). 이는 연속 조건i-- 으로도 사용됨을 의미합니다 . 결정적으로, 각 반복 전에 실행되고 확인 됩니다.
- 
array.length폭발하지 않고 어떻게 시작할 수 있습니까?각 반복 전에 i--실행 되기 때문에 첫 번째 반복에서 실제로범위를 벗어난 배열항목array.length - 1과 관련된 문제를 피하는 항목에 액세스합니다 .undefined
- 
인덱스 0 이전의 반복을 멈추지 않는 이유는 무엇입니까? 조건 i--이 거짓 값으로 평가되면 (0을 생성 할 때) 루프 반복이 중지됩니다 .요령은 --i후행i--연산자 와 달리 감소 하기 전에i값을 산출한다는 것 입니다. 당신의 콘솔은 이것을 증명할 수 있습니다 :> var i = 5; [i, i--, i];[5, 5, 4]따라서 최종 반복에서 i 는 이전에 1 이었고 i--표현식은 0으로 변경 되었지만 실제로는 1 (거짓)을 산출 하므로 조건이 통과합니다. 다음 반복에서 i 는 -1로i--변경 되지만 0 (거짓)이 발생하여 루프 하단에서 즉시 실행이 중단됩니다.루프 전통적인 전방에서 i++그리고++i(더글라스 크록 퍼드 지적한 바와 같이) 교환 할 수있다. 그러나 역 for 루프에서는 감소가 조건 표현식이기 때문에i--인덱스 0에서 항목을 처리 하려면 고수해야합니다 .
하찮은 일
어떤 사람들은 리버스 for루프 에 작은 화살표를 그리고 윙크로 끝나기를 좋아합니다 .
for (var i = array.length; i --> 0 ;) {크레딧은 WYL로 이동하여 리버스 for 루프의 이점과 공포를 보여주었습니다.
답변
일부 C 스타일 언어는 foreach열거를 반복 하는 데 사용 됩니다. JavaScript에서 이것은 for..in루프 구조로 수행됩니다 .
var index,
    value;
for (index in obj) {
    value = obj[index];
}캐치가 있습니다. for..in객체의 열거 가능한 각 멤버와 프로토 타입의 멤버를 반복합니다. 객체의 프로토 타입을 통해 상속 된 값을 읽지 않으려면 속성이 객체에 속하는지 확인하면됩니다.
for (i in obj) {
    if (obj.hasOwnProperty(i)) {
        //do stuff
    }
}또한 ECMAScript 5 는 콜백을 사용하여 배열을 열거하는 데 사용할 수 있는 forEach방법을 추가했습니다 Array.prototype(폴리 필은 문서에 있으므로 여전히 오래된 브라우저에서 사용할 수 있습니다).
arr.forEach(function (val, index, theArray) {
    //do stuff
});Array.prototype.forEach콜백이를 반환 할 때 중단되지 않는다는 점에 유의해야 합니다 false. jQuery 와 Underscore.js 는 each단락 될 수있는 루프를 제공 하기 위해 자체 변형 을 제공합니다.
답변
배열을 반복하려면 표준 3 파트 for루프를 사용하십시오 .
for (var i = 0; i < myArray.length; i++) {
    var arrayItem = myArray[i];
}캐싱 myArray.length또는 반복 하여 일부 성능 최적화를 얻을 수 있습니다 .
답변
나는 이것이 오래된 게시물이라는 것을 알고 있으며 이미 많은 훌륭한 답변이 있습니다. 좀 더 완전성을 위해 AngularJS를 사용하여 다른 것을 던질 것이라고 생각했습니다 . 물론 이것은 Angular를 사용하는 경우에만 적용됩니다. 그럼에도 불구하고 어쨌든 넣고 싶습니다.
angular.forEach2 개의 인수와 선택적인 세 번째 인수를 사용합니다. 첫 번째 인수는 반복 할 객체 (배열)이고 두 번째 인수는 반복자 함수이며 선택적 세 번째 인수는 객체 컨텍스트 (기본적으로 루프 내에서 ‘this’라고 함)입니다.
각도의 forEach 루프를 사용하는 방법에는 여러 가지가 있습니다. 가장 단순하고 아마도 가장 많이 사용되는 것은
var temp = [1, 2, 3];
angular.forEach(temp, function(item) {
    //item will be each element in the array
    //do something
});한 배열에서 다른 배열로 항목을 복사하는 데 유용한 또 다른 방법은
var temp = [1, 2, 3];
var temp2 = [];
angular.forEach(temp, function(item) {
    this.push(item); //"this" refers to the array passed into the optional third parameter so, in this case, temp2.
}, temp2);그렇게 할 필요는 없지만 간단하게 다음을 수행 할 수 있으며 이전 예제와 동일합니다.
angular.forEach(temp, function(item) {
    temp2.push(item);
});이제 angular.forEach내장 바닐라 풍미 for루프 와 달리 기능 을 사용하는 장단점이 있습니다.
찬성
- 쉬운 가독성
- 손쉬운 쓰기
- 가능한 경우 angular.forEachES5 forEach 루프를 사용합니다. forEach 루프가 for 루프보다 훨씬 느리므로 단점 섹션에서 효율성을 얻을 것 입니다. 일관성 있고 표준화 된 것이 좋기 때문에 이것을 전문가라고 언급합니다.
다음과 같은 2 개의 중첩 루프를 고려하십시오. 두 개의 객체 배열이 있고 각 객체에 결과 배열이 포함되어 있다고 가정 해 봅시다. 각 배열에는 문자열 (또는 기타)의 Value 속성이 있습니다. 그리고 각 결과에 대해 반복해야하며 결과가 같으면 몇 가지 조치를 수행하십시오.
angular.forEach(obj1.results, function(result1) {
    angular.forEach(obj2.results, function(result2) {
        if (result1.Value === result2.Value) {
            //do something
        }
    });
});
//exact same with a for loop
for (var i = 0; i < obj1.results.length; i++) {
    for (var j = 0; j < obj2.results.length; j++) {
        if (obj1.results[i].Value === obj2.results[j].Value) {
            //do something
        }
    }
}이것은 매우 간단한 가상의 예이지만, 두 번째 접근 방식을 사용하여 루프 용 트리플 임베디드를 작성했으며 그 문제를 읽고 쓰기 가 매우 어려웠습니다.
단점
- 능률. angular.forEach, 그리고forEach그 문제에 대한 네이티브 는 둘 다 일반 루프 보다 훨씬 느리다for. 약 90 % 느리다 . 따라서 큰 데이터 세트의 경우 기본for루프 를 따르는 것이 가장 좋습니다 .
- 휴식, 계속 또는 반환 지원이 없습니다. continue실제로는 ” 사고 “에 의해 지원되며 , 함수 에서 계속해서 해당 반복에 대한 함수에서 계속되는 명령문을angular.forEach넣습니다 . 이것은 또한 원주민 이 휴식이나 계속을 지원하지 않기 때문입니다 .return;angular.forEach(array, function(item) { if (someConditionIsTrue) return; });forEach
나는 다양한 다른 장단점이있을 것이라고 확신하며, 당신이 적합하다고 생각하는 것을 자유롭게 추가하십시오. 결론적으로, 효율성이 필요한 경우 for루핑 요구에 맞는 기본 루프 만 사용하십시오. 그러나 데이터 세트가 더 작고 가독성 및 쓰기 가능성 대신에 약간의 효율성이 포기된다면, 그 angular.forEach나쁜 소년을 던져 버릴 수 있습니다.
