etc./StackOverFlow

JavaScript의 배열에 대한 For-each

청렴결백한 만능 재주꾼 2021. 9. 30. 00:17
반응형

질문자 :Dante1986


JavaScript를 사용하여 배열의 모든 항목을 반복하려면 어떻게 해야 합니까?

나는 다음과 같다고 생각했다.

 forEach(instance in theArray)

theArray 는 내 배열이지만 이것은 잘못된 것 같습니다.



TL;DR

  • 귀하의 최선의 선택 은 일반적으로

    • for-of 루프(ES2015+ 전용, 사양 | MDN ) - 단순하고 async 친화적
    • forEach (ES5+ 전용, spec | MDN )(또는 그 친척 some 등) - async 친화적이지는 않지만(자세한 내용 참조)
    • 간단한 구식 for 루프 - async 친화적
    • (드물게) 보호 장치 for-in - async 친화적
  • 몇 가지 빠른 "금지 사항":

    • 안전 장치와 함께 사용하거나 적어도 그것이 당신을 물 수 있는 이유를 알고 있지 않는 한 for-in 사용하지 마십시오.
    • 반환 값을 사용하지 않는 경우 map 사용하지 마십시오.
      map [ spec / MDN ] 을 forEach 것처럼 가르치는 사람이 있습니다. 하지만 그게 목적이 아닙니다 . 생성하는 배열을 사용하지 않는다면 map 사용하지 마십시오.)
    • 사용하지 마십시오 forEach 콜백 비동기 작업을 수행하고 당신이 원하는 경우에 forEach 그 작업이 완료 될 때까지 (있기 때문에하지 않습니다) 기다려야.

그러나 읽어, 탐험 더 많이있다 ...


JavaScript에는 배열 및 배열과 유사한 객체를 반복하는 강력한 의미 체계가 있습니다. 저는 그 답을 두 부분으로 나누었습니다. 진정한 배열을 위한 옵션 arguments 객체, 기타 반복 가능한 객체(ES2015+), DOM 컬렉션 등과 같은 배열과 유사한 것들에 대한 옵션입니다.

좋습니다. 옵션을 살펴보겠습니다.

실제 어레이의 경우

5가지 옵션이 있습니다(2개는 기본적으로 영원히 지원되고, 다른 하나는 ECMAScript 5["ES5"]에 의해 추가되고, ECMAScript 2015("ES2015", 일명 "ES6")에 추가됨):

  1. for-of (반복자를 암시적으로 사용) 사용(ES2015+)
  2. forEach 및 관련(ES5+) 사용
  3. 간단한 for 루프 사용
  4. for-in 올바르게 사용
  5. 반복자를 명시적으로 사용(ES2015+)

(여기에서 오래된 사양을 볼 수 있습니다: ES5 , ES2015 하지만 둘 다 대체되었습니다. 현재 편집자의 초안은 항상 여기에 있습니다 .)

세부:

1. for-of 사용(반복자를 암시적으로 사용)(ES2015+)

ES2015는 JavaScript 에 iterator와 iterable을 추가했습니다. 배열은 반복 가능합니다(나중에 보게 될 DOM 컬렉션과 목록뿐만 아니라 Map , Set Iterable 객체는 값에 대한 반복자를 제공합니다. 새로운 for-of 문은 반복자가 반환한 값을 반복합니다.

 const a = ["a", "b", "c"]; for (const val of a) { // You can use `let` instead of `const` if you like console.log(val); } // a // b // c

이보다 간단하지 않습니다! 덮개 아래에서는 배열에서 반복자를 가져오고 반복자가 반환하는 값을 반복합니다. 배열에서 제공하는 반복자는 배열 요소의 값을 처음부터 끝까지 순서대로 제공합니다.

각 루프 반복에 val 범위가 어떻게 지정되는지 확인하십시오. val 을 사용하려고 하면 루프 본문 외부에 존재하지 않기 때문에 실패합니다.

이론적으로 for-of 루프는 여러 함수 호출을 포함합니다(반복자를 가져오기 위한 호출, 각 값을 가져오기 위한 호출). 그것이 사실인 경우에도 걱정할 필요가 없습니다. 함수 호출은 최신 JavaScript 엔진에서 매우 저렴합니다(자세히 forEach [아래]에 대해 귀찮게 했습니다). 그러나 추가적으로 JavaScript 엔진은 배열과 같은 것에 대한 기본 반복자를 다룰 때 (성능이 중요한 코드에서) 이러한 호출을 최적화합니다.

for-of 는 완전히 async 입니다. 루프 본문에서 작업을 직렬로(병렬이 아님) 수행해야 하는 경우 루프 본문에서 await 는 계속하기 전에 약속이 해결될 때까지 기다립니다. 다음은 어리석은 예입니다.

 function delay(ms) { return new Promise(resolve => { setTimeout(resolve, ms); }); } async function showSlowly(messages) { for (const str of messages) { await delay(400); console.log(str); } } showSlowly([ "So", "long", "and", "thanks", "for", "all", "the", "fish!" ]); // `.catch` omitted because we know it never rejects

단어가 각 단어 앞에 지연되어 나타나는 방식에 유의하십시오.

그것은 코딩 스타일의 문제이지만 for-of 는 반복 가능한 모든 것을 반복할 때 가장 먼저 도달하는 것입니다.

2. forEach 및 관련 사용

ES5에 의해 추가된 Array 기능에 액세스할 수 있는 모호하게 현대적인 환경(IE8이 아님)에서 동기 코드만 처리하는 경우(또는 필요하지 않은 경우) forEach ( spec | MDN )를 사용할 수 있습니다. 루프 동안 비동기 프로세스가 완료될 때까지 대기):

 const a = ["a", "b", "c"]; a.forEach((entry) => { console.log(entry); });

forEach 는 콜백 함수와 선택적으로 this 로 사용할 값을 허용합니다(위에서 사용되지 않음). 콜백은 배열의 각 항목에 대해 순서대로 호출되어 희소 배열에 존재하지 않는 항목을 건너뜁니다. 위에서 하나의 매개변수만 사용했지만 콜백은 세 개의 인수로 호출됩니다. 능숙한).

for-of 와 마찬가지로 forEach 는 포함 범위에서 인덱싱 및 값 변수를 선언할 필요가 없다는 장점이 있습니다. 이 경우, 그것들은 반복 함수에 대한 인수로 제공되며, 단지 해당 반복에 대한 범위가 매우 적절합니다.

for-of 와 달리 forEach async 함수를 이해하지 못하고 await 라는 단점이 있습니다. async 함수를 콜백으로 사용하는 경우 forEach 는 계속하기 전에 해당 함수의 약속이 완료될 때까지 기다리지 않습니다. 다음 for-of forEach 를 사용한 async 예제입니다. 초기 지연이 있지만 대기하는 대신 모든 텍스트가 즉시 나타납니다.

 function delay(ms) { return new Promise(resolve => { setTimeout(resolve, ms); }); } async function showSlowly(messages) { messages.forEach(async message => { // Doesn't wait before continuing await delay(400); console.log(message); }); } showSlowly([ "So", "long", "and", "thanks", "for", "all", "the", "fish!" ]); // `.catch` omitted because we know it never rejects

forEach 는 "loop through them all" 함수이지만 ES5는 다음과 같은 몇 가지 다른 유용한 "배열을 통해 작업하고 작업을 수행"하는 함수를 정의했습니다.

  • every ( spec | MDN ) - 콜백이 거짓 값을 처음 반환할 때 반복을 중지합니다.
  • some ( spec | MDN ) - 콜백이 진실 값을 처음 반환할 때 반복을 중지합니다.
  • filter ( spec | MDN ) - 콜백이 진실 값을 반환하는 요소를 포함하는 새 배열을 생성하고 그렇지 않은 값은 생략합니다.
  • map ( spec | MDN ) - 콜백에 의해 반환된 값에서 새 배열을 만듭니다.
  • reduce ( spec | MDN ) - 콜백을 반복적으로 호출하고 이전 값을 전달하여 값을 생성합니다. 자세한 내용은 사양을 참조하십시오
  • reduceRight ( spec | MDN ) - reduce 와 유사하지만 오름차순이 아닌 내림차순으로 작동합니다.

forEach 와 마찬가지로 async 함수를 콜백으로 사용하면 그 중 어느 것도 함수의 약속이 완료될 때까지 기다리지 않습니다. 그 의미는:

  • async 함수 콜백을 사용하는 every , somefilter 결코 적절하지 않습니다. 왜냐하면 반환된 약속을 마치 진실한 값인 것처럼 취급하기 때문입니다. 그들은 약속이 해결될 때까지 기다렸다가 이행 값을 사용 하지 않습니다.
  • 사용하여 async 자주와 적절한 기능 콜백을 map 목표는 아마도 약속 콤비 기능 중 하나 (에 전달하는, 약속의 배열로 무언가의 배열을 설정하는 경우, Promise.all , Promise.race , promise.allSettled , 또는 Promise.any ).
  • async 함수 콜백을 사용하는 것은 (다시) 콜백이 항상 약속을 반환하기 때문에 reduce 또는 reduceRight 거의 적합하지 않습니다. reduce ( const promise = array.reduce((p, element) => p.then(/*...something using `element`...*/)); 를 사용하는 배열에서 약속 체인을 구축하는 관용구가 있습니다. const promise = array.reduce((p, element) => p.then(/*...something using `element`...*/)); ) 그러나 일반적으로 이러한 경우 async for-of 또는 for 루프가 더 명확하고 디버그하기 쉽습니다.

3. 간단한 for 루프 사용

때로는 오래된 방법이 가장 좋습니다.

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

배열의 길이가 루프 동안 변경되지 않습니다, 그것은 (가능성) 성능에 민감한 코드의 경우, 앞까지 길이를 잡아 약간 더 복잡한 버전은 작은 조금 더 빠를 수 있습니다

 const a = ["a", "b", "c"]; for (let index = 0, len = a.length; index < len; ++index) { console.log(a[index]); }

및/또는 거꾸로 계산:

 const a = ["a", "b", "c"]; for (let index = a.length - 1; index >= 0; --index) { console.log(a[index]); }

그러나 최신 JavaScript 엔진을 사용하면 마지막 남은 즙을 꺼낼 필요가 거의 없습니다.

ES2015 이전에는 루프 변수가 포함 범위에 있어야 했습니다. var 에는 블록 수준 범위가 아닌 기능 수준 범위만 있기 때문입니다. 그러나 위의 예에서 보았듯이 for 내에서 let 을 사용하여 변수 범위를 루프로만 지정할 수 있습니다. 그리고 그렇게 하면 index 변수가 다시 생성됩니다. 즉, 루프 본문에서 생성된 클로저 index 대한 참조를 유지하므로 오래된 "루프 내 클로저" 문제가 해결됩니다.

 const divs = document.querySelectorAll("div"); for (let index = 0; index < divs.length; ++index) { divs[index].addEventListener('click', e => { console.log("Index is: " + index); }); }
 <div>zero</div> <div>one</div> <div>two</div> <div>three</div> <div>four</div>

위의 경우 첫 번째를 클릭하면 "Index is: 0"이 표시되고 마지막을 클릭하면 "Index is: 4"가 표시됩니다. let 대신 var 를 사용하면 작동하지 않습니다 .

마찬가지로 for-of , for 루프에서 잘 작동 async 기능을합니다. for 루프를 사용한 이전 예제입니다.

 function delay(ms) { return new Promise(resolve => { setTimeout(resolve, ms); }); } async function showSlowly(messages) { for (let i = 0; i < messages.length; ++i) { await delay(400); console.log(messages[i]); } } showSlowly([ "So", "long", "and", "thanks", "for", "all", "the", "fish!" ]); // `.catch` omitted because we know it never rejects

4. for-in 올바르게 사용

for-in 은 배열을 반복하는 것이 아니라 객체의 속성 이름을 반복하는 것입니다. 배열이 객체라는 사실의 부산물로 배열을 반복하는 데 종종 작동하는 것처럼 보이지만 배열 인덱스만 반복하는 것이 아니라 개체의 모든 열거 가능한 속성(상속된 속성 포함)을 반복합니다. (또한 예전에는 순서를 지정하지 않았는데 지금은 [자세한 내용은 이 다른 답변 ] 이지만 지금은 순서가 지정되어 있어도 규칙이 복잡하고 예외가 있으며 순서에 의존하는 것은 그렇지 않습니다. 모범 사례.)

for-in 의 유일한 실제 사용 사례는 다음과 같습니다.

  • 엄청난 간격이 있는 희소 배열이거나
  • 요소가 아닌 속성을 사용 중이고 루프에 포함하려는 경우

첫 번째 예만 살펴보면 다음과 같이 for-in 을 사용하여 희소 배열 요소를 방문할 수 있습니다.

 // `a` is a sparse array const a = []; a[0] = "a"; a[10] = "b"; a[10000] = "c"; for (const name in a) { if (a.hasOwnProperty(name) && // These checks are /^0$|^[1-9]\d*$/.test(name) && // explained name <= 4294967294 // below ) { console.log(a[name]); } }

세 가지 확인 사항에 유의하십시오.

  1. 객체가 해당 이름으로 고유한 속성을 갖고 있음(프로토타입에서 상속한 속성이 아님)

  2. 이름이 모두 십진수(예: 과학 표기법이 아닌 일반 문자열 형식)이며,

  3. 숫자로 강제 변환될 때 이름의 값은 <= 2^32 - 2(4,294,967,294)입니다. 그 숫자는 어디에서 왔습니까? 사양에서 배열 인덱스 정의의 일부입니다. 다른 숫자(정수가 아닌 숫자, 음수, 2^32 - 2보다 큰 숫자)는 배열 인덱스가 아닙니다. 2^32 - 2인 이유는 가장 큰 인덱스 값이 배열의 length 가 가질 수 있는 최대값인 2^32 - 1보다 1 작게 만들기 때문입니다. (예: 배열의 길이는 32비트 부호 없는 정수에 맞습니다.)

물론 인라인 코드에서는 그렇게 하지 않을 것입니다. 유틸리티 함수를 작성합니다. 혹시:

 // Utility function for antiquated environments without `forEach` const hasOwn = Object.prototype.hasOwnProperty.call.bind(Object.prototype.hasOwnProperty); const rexNum = /^0$|^[1-9]\d*$/; function sparseEach(array, callback, thisArg) { for (const name in array) { const index = +name; if (hasOwn(a, name) && rexNum.test(name) && index <= 4294967294 ) { callback.call(thisArg, array[name], index, array); } } } const a = []; a[5] = "five"; a[10] = "ten"; a[100000] = "one hundred thousand"; ab = "bee"; sparseEach(a, (value, index) => { console.log("Value at " + index + " is " + value); });

hasOwnProperty 대부분의 코드는 hasOwnProperty 검사만 수행합니다.

for 와 마찬가지로 for-in 은 내부 작업을 연속적으로 수행해야 하는 경우 비동기 함수에서 잘 작동합니다.

 function delay(ms) { return new Promise(resolve => { setTimeout(resolve, ms); }); } async function showSlowly(messages) { for (const name in messages) { if (messages.hasOwnProperty(name)) { await delay(400); console.log(messages[name]); } } } showSlowly([ "So", "long", "and", "thanks", "for", "all", "the", "fish!" ]); // `.catch` omitted because we know it never rejects

5. 반복자를 명시적으로 사용(ES2015+)

for-of 는 암시적으로 반복자를 사용하여 모든 작업을 수행합니다. 때때로 반복자를 명시적으로 사용하고 싶을 수도 있습니다. 다음과 같습니다.

 const a = ["a", "b", "c"]; const it = a.values(); // Or `const it = a[Symbol.iterator]();` if you like let entry; while (!(entry = it.next()).done) { console.log(entry.value); }

반복자는 사양의 반복자 정의와 일치하는 개체입니다. 그 next 메서드는 호출할 때마다 새 결과 개체를 반환합니다. 결과 객체에는 done 여부를 알려주는 done 속성과 해당 반복에 대한 value ( donefalse 이면 value undefined 이면 선택 사항입니다.)

value 얻는 것은 반복자에 따라 다릅니다. 어레이에서, 디폴트는 반복자 각 배열 요소의 값 (제공 "a" , "b""c" 이전 예에서 참조). 배열에는 반복자를 반환하는 세 가지 다른 메서드도 있습니다.

  • values() : 기본 반복자를 반환하는 [Symbol.iterator] 메서드의 별칭입니다.
  • keys() : 배열의 각 키(인덱스)를 제공하는 반복자를 반환합니다. 위의 예에서 "0" , "1" , "2" (예, 문자열)를 제공합니다.
  • entries() [key, value] 배열을 제공하는 반복자를 반환합니다.

next 를 호출할 때까지 진행되지 않기 때문에 async 함수 루프에서 잘 작동합니다. 다음은 반복자를 명시적으로 사용하는 이전 for-of

 function delay(ms) { return new Promise(resolve => { setTimeout(resolve, ms); }); } async function showSlowly(messages) { const it = messages.values() while (!(entry = it.next()).done) { await delay(400); console.log(entry.value); } } showSlowly([ "So", "long", "and", "thanks", "for", "all", "the", "fish!" ]); // `.catch` omitted because we know it never rejects

배열과 같은 객체의 경우

이외에도 사실 배열에서, 또한 배열과 같은이 객체가있는 length : 모든 숫자 이름을 가진 특성과 속성을 NodeList 경우 , HTMLCollection 경우arguments 어떻게 그 내용을 통해 우리에게 루프를 할 등, 객체?

위의 옵션을 대부분 사용

위의 배열 접근 방식 중 적어도 일부, 아마도 대부분 또는 전부는 배열과 유사한 객체에 똑같이 잘 적용됩니다.

  1. for-of (반복자를 암시적으로 사용) 사용(ES2015+)

    for-of객체가 제공하는 반복자 를 사용합니다(있는 경우). 여기에는 호스트 제공 개체(예: DOM 컬렉션 및 목록)가 포함됩니다. 예를 들어 getElementsByXYZ 메서드의 HTMLCollection 인스턴스 querySelectorAll NodeList 인스턴스는 모두 반복을 지원합니다. (이것은 HTML 및 DOM 사양에 의해 매우 length 및 색인화된 액세스가 있는 모든 객체는 자동으로 반복 가능합니다. iterable로 표시할 필요 가 없습니다 iterable 가능할 뿐만 아니라 컬렉션에만 사용됩니다. forEach , values , keysentries 메소드를 지원 NodeListHTMLCollection 은 지원하지 않지만 둘 다 반복 가능합니다.)

    div 요소를 반복하는 예입니다.

 const divs = document.querySelectorAll("div"); for (const div of divs) { div.textContent = Math.random(); }
 <div>zero</div> <div>one</div> <div>two</div> <div>three</div> <div>four</div>

  1. forEach 및 관련(ES5+) 사용

    Array.prototype 의 다양한 기능 Function#call ( spec | MDN ) 또는 Function#apply ( spec | MDN )를 통해 배열과 유사한 객체에서 사용할 수 있습니다. (IE8 또는 이전 버전을 처리해야 하는 경우 [ouch], 이 답변 끝에 있는 "호스트 제공 개체에 대한 주의 사항"을 참조하세요. 그러나 막연한 최신 브라우저에서는 문제가 되지 않습니다.)

    당신이 사용하고자 가정 forEach A의 NodechildNodes (AN되고, 수집 HTMLCollection ,이 없습니다 forEach 기본적으로). 당신은 이것을 할 것입니다 :

     Array.prototype.forEach.call(node.childNodes, (child) => { // Do something with `child` });

    (그러나 node.childNodes에서 for-of 를 사용할 수 있다는 점 node.childNodes .)

    이 작업을 많이 수행하려는 경우 재사용을 위해 함수 참조의 복사본을 변수로 가져오고 싶을 수 있습니다. 예:

     // (This is all presumably in a module or some scoping function) const forEach = Array.prototype.forEach.call.bind(Array.prototype.forEach); // Then later... forEach(node.childNodes, (child) => { // Do something with `child` });
  2. 간단한 for 루프 사용

    아마도 분명히 간단한 for 루프는 배열과 유사한 객체에 대해 작동합니다.

  3. 반복자를 명시적으로 사용(ES2015+)

    1번 참조.

당신은 멀리받을 수 있습니다 for-in (안전 장치), 그러나이 더 적절한 모든 옵션을 시도 할 이유가 없습니다.

실제 배열 만들기

다른 경우에는 배열과 유사한 객체를 실제 배열로 변환할 수 있습니다. 놀라울 정도로 쉽습니다.

  1. Array.from 사용

    Array.from (사양) | (MDN) (ES2015+이지만 쉽게 폴리필됨)은 배열과 유사한 객체에서 배열을 생성하고 선택적으로 매핑 함수를 통해 항목을 먼저 전달합니다. 그래서:

     const divs = Array.from(document.querySelectorAll("div"));

    querySelectorAll NodeList 를 가져와서 배열을 만듭니다.

    어떤 식으로든 내용을 매핑하려는 경우 매핑 기능이 편리합니다. 예를 들어, 주어진 클래스가 있는 요소의 태그 이름 배열을 얻으려면 다음을 수행하십시오.

     // Typical use (with an arrow function): const divs = Array.from(document.querySelectorAll(".some-class"), element => element.tagName); // Traditional function (since `Array.from` can be polyfilled): var divs = Array.from(document.querySelectorAll(".some-class"), function(element) { return element.tagName; });
  2. 스프레드 구문 사용( ... )

    ES2015의 스프레드 구문 을 사용하는 것도 가능합니다. for-of 와 마찬가지로 이것은 객체가 제공하는 반복자를 사용합니다(이전 섹션의 #1 참조).

     const trueArray = [...iterableObject];

    예를 들어, NodeList 를 실제 배열로 변환하려는 경우 스프레드 구문을 사용하면 다음과 같이 매우 간단해집니다.

     const divs = [...document.querySelectorAll("div")];
  3. 배열의 slice

    위에서 언급한 다른 방법과 마찬가지로 "의도적으로 일반적"이므로 다음과 같이 배열과 유사한 객체와 함께 사용할 수 있는 배열의 slice

     const trueArray = Array.prototype.slice.call(arrayLikeObject);

    예를 들어 NodeList 를 실제 배열로 변환하려면 다음과 같이 할 수 있습니다.

     const divs = Array.prototype.slice.call(document.querySelectorAll("div"));

    (여전히 IE8[ouch]을 처리해야 한다면 실패합니다. IE8에서는 호스트 제공 개체를 this 같이 사용할 수 없었습니다.)

호스트 제공 개체에 대한 주의 사항

호스트 제공 배열과 유사한 객체(예: JavaScript 엔진이 아닌 브라우저에서 제공하는 DOM 컬렉션 등)와 함께 Array.prototype 함수를 사용하는 경우 IE8과 같은 구식 브라우저에서는 반드시 그런 식으로 처리하지 않으므로 지원하려면 대상 환경에서 테스트해야 합니다. 그러나 막연하게 현대적인 브라우저에서는 문제가 되지 않습니다. (비 브라우저 환경의 경우 당연히 환경에 따라 다릅니다.)


T.J. Crowder

참고 : 이 답변은 절망적으로 구식입니다. 보다 현대적인 접근 방식 을 위해 array 에서 사용할 수 있는 메서드를 살펴보세요. 관심 방법은 다음과 같습니다.

  • 각각
  • 지도
  • 필터
  • 지퍼
  • 줄이다
  • 모든
  • 일부

JavaScript 에서 배열을 반복하는 표준 방법은 바닐라 for 루프입니다.

 var length = arr.length, element = null; for (var i = 0; i < length; i++) { element = arr[i]; // Do something with element }

그러나 이 접근 방식은 조밀한 배열이 있고 각 인덱스가 요소에 의해 점유되는 경우에만 좋습니다. 배열이 희소한 경우 배열에 실제로 존재하지 않는 많은 인덱스를 반복하므로 이 접근 방식을 사용하면 성능 문제가 발생할 수 있습니다. 이 경우 for .. in 루프가 더 나은 아이디어일 수 있습니다. 그러나 for..in 루프도 레거시 브라우저에서 열거되거나 enumerable 것으로 정의됩니다.

ECMAScript 5 에는 어레이 프로토타입에 forEach 메소드가 있지만 레거시 브라우저에서는 지원되지 않습니다. 따라서 일관되게 사용할 수 있으려면 이를 지원하는 환경(예: 서버 측 JavaScript용 Node.js )이 있거나 "Polyfill"을 사용해야 합니다. 그러나 이 기능에 대한 Polyfill은 사소하고 코드를 더 쉽게 읽을 수 있도록 하므로 포함하는 것이 좋은 Polyfill입니다.


PatrikAkerstrand

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]. }

Poonam

뒤로 루프

나는 역방향 for 루프가 여기에서 언급될 가치가 있다고 생각합니다:

 for (var i = array.length; i--; ) { // process array[i] }

장점:

  • len 변수를 선언하거나 각 반복에서 array.length와 비교할 필요가 없습니다. 둘 중 하나는 array.length
  • DOM에서 형제를 역순으로 제거하는 것이 일반적으로 더 효율적 입니다. (브라우저는 내부 배열의 요소 이동을 줄여야 합니다.)
  • 또는 인덱스 후에 반복하면서 배열을 수정하는 경우 (예컨대 제거하거나에서 아이템을 삽입 array[i] 다음 포워드 루프 위치로 왼쪽으로 이동할 항목을 이동 것) 나, 또는 상기 I 재 처리 오른쪽으로 이동한 항목입니다. 전통적인 for 루프에서는 처리가 필요한 다음 항목 - 1을 가리키도록 i 를 업데이트 할 수 있지만 단순히 반복 방향을 바꾸는 것이 더 간단 하고 우아한 솔루션인 경우가 많습니다.
  • 유사하게, 중첩된 DOM 요소를 수정하거나 제거할 때 역으로 처리하면 오류를 피할 수 있습니다 . 예를 들어, 자식을 처리하기 전에 부모 노드의 innerHTML을 수정하는 것을 고려하십시오. 자식 노드에 도달하면 DOM에서 분리되고 부모의 innerHTML이 작성될 때 새로 생성된 자식으로 대체됩니다.
  • 사용 가능한 다른 옵션보다 입력 및 읽기더 짧습니다. forEach() 및 ES6에 for ... of .

단점:

  • 항목을 역순으로 처리합니다. 결과에서 새 배열을 만들거나 화면에 인쇄하는 경우 자연스럽게 원래 순서와 관련 하여 출력이 반전됩니다.
  • 순서를 유지하기 위해 형제를 DOM에 첫 번째 자식으로 반복적으로 삽입하는 것은 효율성이 떨어집니다 . (브라우저는 계속 올바른 방향으로 이동해야 합니다.) DOM 노드를 효율적이고 순서대로 생성하려면 루프를 앞으로 반복하고 평소처럼 추가하면 됩니다(또한 "문서 조각"도 사용).
  • 역루프는 주니어 개발자들에게 혼란스럽습니다. (전망에 따라 장점이라고 생각하시면 됩니다.)

항상 사용해야합니까?

일부 개발자는 순방향 루프에 대한 합당한 이유가 없는 한 기본적으로 역방향 for 루프를 사용합니다.

성능 향상은 일반적으로 미미하지만 다음과 같이 비명을 지릅니다.

"목록에 있는 모든 항목에 대해 이 작업을 수행하면 됩니다. 순서는 상관없습니다!"

그러나 당신이 순서에 대한 관리를 수행 할 때 이러한 경우를 구별하고, 정말 역 루프 필요성을하기 때문에, 실제로 의도 신뢰할 수있는 표시되지 않습니다 연습한다. forEachUnordered() 와 같이 호출할 수 있는 "관심 없음" 의도를 정확하게 표현하려면 다른 구성이 필요합니다.

순서가 중요하지 않고 효율성 이 문제인 경우(게임 또는 애니메이션 엔진의 가장 안쪽 루프에서), 역방향 for 루프를 이동 패턴으로 사용하는 것이 허용될 수 있습니다. 기존 코드에서 역 for 루프를 본다고 해서 반드시 순서가 관련 이 없다는 것을 의미하지는 않습니다!

forEach()를 사용하는 것이 더 좋았습니다.

일반적으로 명료성과 안전성 이 더 중요한 상위 수준 코드의 경우 Array::forEach 를 반복의 기본 패턴으로 사용하는 것이 좋습니다 for..of 를 사용하는 것을 선호하지만). forEach 를 선호하는 이유는 다음과 같습니다.

  • 읽는 것이 더 명확합니다.
  • 이는 i 가 블록 내에서 이동하지 않을 것임을 나타냅니다 forwhile 루프에 숨어 있을 수 있는 놀라움입니다).
  • 폐쇄에 대한 자유로운 범위를 제공합니다.
  • 지역 변수의 누출과 외부 변수와의 우발적인 충돌(및 돌연변이)을 줄입니다.

그런 다음 코드에서 역방향 for 루프를 볼 때 이는 합당한 이유(아마도 위에서 설명한 이유 중 하나)로 인해 역방향이라는 힌트입니다. 그리고 전통적인 정방향 for 루프를 보면 시프팅이 발생할 수 있음을 나타낼 수 있습니다.

(의도에 대한 논의가 이해가 되지 않는다면 프로그래밍 스타일과 두뇌 에 대한 Crockford의 강의를 시청하는 것이 귀하와 귀하의 코드에 도움이 될 것입니다.)

이제 for..of를 사용하는 것이 더 좋습니다.

for..of 또는 forEach() 가 선호되는지 여부에 대한 논쟁이 있습니다.

개인적으로 성능이나 축소가 주요 관심사가 되지 않는 한 가장 읽기 쉬운 것을 사용하는 경향이 있습니다. 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 있는 항목에 액세스하여 Array-out-of-bounds undefined 항목과 관련된 문제를 방지합니다.

  • 인덱스 0 이전에 반복을 중지하지 않는 이유는 무엇입니까?

    루프는 조건 i-- 가 잘못된 값으로 평가될 때(0을 산출할 때) 반복을 중지합니다.

    트릭은 --i 와 달리 후행 i-- 연산자가 i 감소시키지만 감소하기 전에 값을 산출한다는 것입니다. 콘솔에서 다음을 보여줄 수 있습니다.

    > var i = 5; [i, i--, i];

    [5, 5, 4]

    따라서 최종 반복에서 i 는 이전에 1 이었고 i-- 식은 이를 0으로 변경하지만 실제로는 1 (truthy)을 생성하므로 조건이 통과합니다. 다음 반복에서 i--i-1로 변경하지만 0 (거짓)을 생성하여 실행이 루프의 맨 아래에서 즉시 삭제되도록 합니다.

    전통적인 forwards for 루프에서 i++++i 는 서로 바꿔 사용할 수 있습니다(Douglas Crockford가 지적한 대로). 그러나 반대로 for 루프에서는 감소가 조건식이기도 하므로 인덱스 0에서 항목을 처리하려면 i--


하찮은 일

for 루프에서 역방향으로 작은 화살표를 그리고 윙크로 끝나는 것을 좋아합니다.

 for (var i = array.length; i --> 0 ;) {

역 for 루프의 이점과 공포를 보여주는 크레딧은 WYL로 이동합니다.


joeytwiddle

일부 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 Array.prototype forEach 메서드를 추가했습니다. 이 메서드는 calback을 사용하여 배열을 열거하는 데 사용할 수 있습니다(폴리필은 문서에 있으므로 이전 브라우저에서 계속 사용할 수 있습니다).

 arr.forEach(function (val, index, theArray) { //do stuff });

false Array.prototype.forEach 가 중단되지 않는다는 점에 유의하는 것이 중요합니다. jQueryUnderscore.js 는 단락될 수 있는 루프를 제공하기 위해 each 에 대해 고유한 변형을 제공합니다.


zzzzBov

배열을 반복하려면 표준 세 부분으로 구성된 for 루프를 사용하십시오.

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

myArray.length 를 캐싱하거나 역순으로 반복하여 성능을 최적화할 수 있습니다.


Quentin

배열을 비워도 상관없다면:

 var x; while(x = y.pop()){ alert(x); //do something }

x y 의 마지막 값을 포함하고 배열에서 제거됩니다. y 에서 첫 번째 항목을 제공하고 제거하는 shift() 를 사용할 수도 있습니다.


gaby de wilde

나는 이것이 오래된 게시물이라는 것을 알고 있으며 이미 많은 훌륭한 답변이 있습니다. 조금 더 완전성을 위해 AngularJS를 사용하여 다른 것을 던질 것이라고 생각했습니다. 물론 이것은 Angular를 사용하는 경우에만 적용됩니다. 분명히 그럼에도 불구하고 어쨌든 넣고 싶습니다.

angular.forEach 는 2개의 인수와 선택적인 세 번째 인수를 취합니다. 첫 번째 인수는 반복할 객체(배열)이고, 두 번째 인수는 반복자 함수이며, 선택적 세 번째 인수는 객체 컨텍스트(기본적으로 루프 내부에서 'this'라고 함)입니다.

Angular의 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); });

이제 기본 제공되는 바닐라 맛 for angular.forEach 함수를 사용하면 장단점이 있습니다.

장점

  • 쉬운 가독성
  • 쉬운 쓰기성
  • 사용 가능한 경우 angular.forEach 는 ES5 forEach 루프를 사용합니다. 이제 forEach 루프가 for 루프보다 훨씬 느리기 때문에 단점 섹션에서 효율성을 살펴보겠습니다. 일관성 있고 표준화된 것이 좋기 때문에 이것을 전문가라고 언급합니다.

정확히 동일한 작업을 수행하는 다음 2개의 중첩 루프를 고려하십시오. 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 } } }

이것은 매우 간단한 가상의 예이지만 두 번째 접근 방식을 사용하여 삼중 임베디드 for 루프를 작성했으며 그 문제에 대해 읽고 쓰기 가 매우 어려웠습니다.

단점

  • 능률. angular.forEach 와 네이티브 forEach 는 둘 다 for 루프보다 훨씬 느립니다....약 90% 더 느립니다 . 따라서 대규모 데이터 세트의 경우 기본 for 루프를 사용하는 것이 가장 좋습니다.
  • 중단, 계속 또는 반환 지원이 없습니다. continue 는 실제로 " 사고 "에 angular.forEach 에서 계속하려면 단순하게 return; angular.forEach(array, function(item) { if (someConditionIsTrue) return; }); 그러면 해당 반복에 대한 기능을 계속 벗어나게 됩니다. 이는 네이티브 forEach 가 break나 continue도 지원하지 않기 때문이기도 합니다.

이 외에도 다양한 장단점이 있을 거라 생각하며, 적절하다고 생각되는 부분을 자유롭게 추가해 주시기 바랍니다. 결론적으로 효율성이 필요한 경우 반복 요구 사항에 대해 for 그러나 데이터 세트가 더 작고 가독성과 쓰기 가능성을 위해 어느 정도 효율성을 포기하는 것이 괜찮다면 반드시 angular.forEach 를 그 나쁜 소년에게 던지십시오.


user2359695

forEach 구현( jsFiddle 참조 ):

 function forEach(list,callback) { var length = list.length; for (var n = 0; n < length; n++) { callback.call(list[n]); } } var myArray = ['hello','world']; forEach( myArray, function(){ alert(this); // do something } );

nmoliveira

ECMAScript 6 기준:

 list = [0, 1, 2, 3] for (let obj of list) { console.log(obj) }

Where of in 과 관련된 기이함을 피하고 다른 언어 for 루프처럼 작동하게 leti 함수 내에서가 아니라 루프 내에서 바인드합니다.

중괄호( {} )는 명령이 하나만 있는 경우(예: 위의 예에서) 생략할 수 있습니다.


Zaz

아마도 for(i = 0; i < array.length; i++) 루프는 최선의 선택이 아닙니다. 왜요? 다음이 있는 경우:

 var array = new Array(); array[1] = "Hello"; array[7] = "World"; array[11] = "!";

이 메서드는 array[0] 에서 array[2] 를 호출합니다. 첫째, 이것은 당신이 가지고 있지 않은 변수를 첫째로 참조할 것이고, 둘째는 배열에 변수가 없을 것이고, 셋째는 코드를 더 굵게 만들 것입니다. 여기 보세요, 제가 사용하는 방법은 다음과 같습니다.

 for(var i in array){ var el = array[i]; //If you want 'i' to be INT just put parseInt(i) //Do something with el }

그리고 그것을 함수로 만들고 싶다면 다음과 같이 할 수 있습니다.

 function foreach(array, call){ for(var i in array){ call(array[i]); } }

깨고 싶다면 조금 더 논리:

 function foreach(array, call){ for(var i in array){ if(call(array[i]) == false){ break; } } }

예시:

 foreach(array, function(el){ if(el != "!"){ console.log(el); } else { console.log(el+"!!"); } });

다음을 반환합니다.

 //Hello //World //!!!

Federico Piragua

jQuery 에는 다음과 같이 세 가지 foreach

 var a = [3,2]; $(a).each(function(){console.log(this.valueOf())}); //Method 1 $.each(a, function(){console.log(this.valueOf())}); //Method 2 $.each($(a), function(){console.log(this.valueOf())}); //Method 3

Rajesh Paul

이제 쉬운 해결책은 underscore.js 라이브러리 를 사용하는 것입니다. each 과 같은 많은 유용한 도구를 제공하고 가능한 경우 forEach 작업을 자동으로 위임합니다.

작동 방식에 대한 CodePen의 예 는 다음과 같습니다.

 var arr = ["elemA", "elemB", "elemC"]; _.each(arr, function(elem, index, ar) { ... });

또한보십시오


Micka

네이티브 JavaScript for each 루프가 없습니다. 라이브러리를 사용하여 이 기능을 사용하거나( Underscore.js 권장) 간단한 for in 루프를 사용할 수 있습니다.

 for (var instance in objects) { ... }

그러나 주 이유는 더 간단한을 사용하는 것이있을 수 있음 for 루프 (스택 오버플로 질문을 참조 왜 사용 "에 대한 ...에서"배열 반복 나쁜 생각? )

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

joidegn

이것은 index가 0에서 시작하는 NON-sparse list의 iterator입니다. 이것은 document.getElementsByTagName 또는 document.querySelectorAll을 처리할 때 일반적인 시나리오입니다.

 function each( fn, data ) { if(typeof fn == 'string') eval('fn = function(data, i){' + fn + '}'); for(var i=0, L=this.length; i < L; i++) fn.call( this[i], data, i ); return this; } Array.prototype.each = each;

사용 예:

예 #1

 var arr = []; [1, 2, 3].each( function(a){ a.push( this * this}, arr); arr = [1, 4, 9]

예 #2

 each.call(document.getElementsByTagName('p'), "this.className = data;",'blue');

각 p 태그는 class="blue"

예 #3

 each.call(document.getElementsByTagName('p'), "if( i % 2 == 0) this.className = data;", 'red' );

다른 모든 p 태그는 class="red" >

예 #4

 each.call(document.querySelectorAll('p.blue'), function(newClass, i) { if( i < 20 ) this.className = newClass; }, 'green' );

그리고 마지막으로 처음 20개의 파란색 p 태그가 녹색으로 변경되었습니다.

문자열을 함수로 사용할 때 주의: 함수는 컨텍스트 외부에서 생성되며 변수 범위 지정이 확실한 경우에만 사용해야 합니다. 그렇지 않으면 범위 지정이 더 직관적인 함수를 전달하는 것이 좋습니다.


Tim

아래와 같이 JavaScript에서 배열을 반복 하는 몇 가지 방법이 있습니다.

for - 가장 일반적인 것 입니다. 루핑을 위한 전체 코드 블록

 var languages = ["Java", "JavaScript", "C#", "Python"]; var i, len, text; for (i = 0, len = languages.length, text = ""; i < len; i++) { text += languages[i] + "<br>"; } document.getElementById("example").innerHTML = text;
 <p id="example"></p>

while - 조건이 완료되는 동안 루프. 가장 빠른 루프인 것 같습니다.

 var text = ""; var i = 0; while (i < 10) { text += i + ") something<br>"; i++; } document.getElementById("example").innerHTML = text;
 <p id="example"></p>

do/while - 조건이 참인 동안 코드 블록을 순환하며, 적어도 한 번 실행됩니다.

 var text = "" var i = 0; do { text += i + ") something <br>"; i++; } while (i < 10); document.getElementById("example").innerHTML = text;
 <p id="example"></p>

기능 루프 - forEach , map , filter , 또한 reduce (함수를 통해 루프하지만 배열 등으로 작업을 수행해야 하는 경우 사용됩니다.

 // For example, in this case we loop through the number and double them up using the map function var numbers = [65, 44, 12, 4]; document.getElementById("example").innerHTML = numbers.map(function(num){return num * 2});
 <p id="example"></p>

배열의 함수형 프로그래밍에 대한 자세한 내용과 예제 는 JavaScript의 함수형 프로그래밍: map, filter 및 reduce 블로그 게시물을 참조하세요.


Alireza

ECMAScript 5(JavaScript 버전)는 배열과 함께 작동합니다.

forEach - 배열의 모든 항목을 반복하고 각 항목에 필요한 모든 작업을 수행합니다.

 ['C', 'D', 'E'].forEach(function(element, index) { console.log(element + " is #" + (index+1) + " in the musical scale"); }); // Output // C is the #1 in musical scale // D is the #2 in musical scale // E is the #3 in musical scale

일부 내장 기능을 사용하여 어레이 작업에 더 관심이 있는 경우.

map - 콜백 함수의 결과로 새로운 배열을 생성합니다. 이 방법은 배열 요소의 형식을 지정해야 할 때 사용하는 것이 좋습니다.

 // Let's upper case the items in the array ['bob', 'joe', 'jen'].map(function(elem) { return elem.toUpperCase(); }); // Output: ['BOB', 'JOE', 'JEN']

reduce - 이름에서 알 수 있듯이 현재 요소와 이전 실행 결과를 전달하는 주어진 함수를 호출하여 배열을 단일 값으로 줄입니다.

 [1,2,3,4].reduce(function(previous, current) { return previous + current; }); // Output: 10 // 1st iteration: previous=1, current=2 => result=3 // 2nd iteration: previous=3, current=3 => result=6 // 3rd iteration: previous=6, current=4 => result=10

every - 배열의 모든 요소가 콜백 함수의 테스트를 통과하면 true 또는 false를 반환합니다.

 // Check if everybody has 18 years old of more. var ages = [30, 43, 18, 5]; ages.every(function(elem) { return elem >= 18; }); // Output: false

필터 - 필터가 주어진 함수에 대해 true를 반환하는 요소가 있는 배열을 반환한다는 점을 제외하고는 every와 매우 유사합니다.

 // Finding the even numbers [1,2,3,4,5,6].filter(function(elem){ return (elem % 2 == 0) }); // Output: [2,4,6]

Anil Kumar Arya

forEach 에 침입할 수 있는 기능이 내장되어 있지 않습니다. 실행을 중단하려면 아래와 같이 Array#some

 [1,2,3].some(function(number) { return number === 1; });

이것은 some 가 true를 반환하여 나머지 실행을 단락시키기 때문에 작동합니다. 원래 답변 일부는 Array 프로토타입을 참조하십시오.


Priyanshu Chauhan

나는 또한 이것을 역 루프의 구성으로 추가하고 이 구문도 원하는 사람을 위해 위의 답변을 추가하고 싶습니다.

 var foo = [object,object,object]; for (var i = foo.length, item; item = foo[--i];) { console.log(item); }

장점:

이점: 첫 번째에 이미 참조가 있으므로 나중에 다른 줄로 선언할 필요가 없습니다. 객체 배열을 반복할 때 편리합니다.

단점:

이것은 참조가 false - false(정의되지 않음 등)일 때마다 중단됩니다. 그래도 장점으로 사용할 수 있습니다. 그러나 읽기가 조금 더 어려울 것입니다. 또한 브라우저에 따라 원래 브라우저보다 빠르게 작동하도록 최적화되지 않을 수도 있습니다.


Volkan Seçkin Akbayır

$.map 사용하는 jQuery 방식 :

 var data = [1, 2, 3, 4, 5, 6, 7]; var newData = $.map(data, function(element) { if (element % 2 == 0) { return element; } }); // newData = [2, 4, 6];

Daniel W.

ECMAScript 6 구조 분해스프레드 연산자와 함께 루프 사용

일부 JavaScript 베테랑은 그것을 지저분하다고 생각할 수도 있지만, 스프레드 연산자의 구조화 및 사용은 ECMAScript 6을 처음 접하는 사람들에게 더 사람이 읽기 쉽고 미적으로 유용한 것으로 입증되었습니다. 주니어나 다른 사람들이 유용하게 사용할 수 있습니다.

다음 예제에서는 for...of 문과 .forEach 메서드를 사용합니다.

실시 예 6, 7, 8과 같은 기능적인 루프가 사용될 수있다 .map , .filter , .reduce , .sort , .every , .some . 이러한 방법에 대한 자세한 내용은 Array Object 를 확인하십시오.

예 1: 일반적인 for...of 루프 - 여기에는 트릭이 없습니다.

 let arrSimple = ['a', 'b', 'c']; for (let letter of arrSimple) { console.log(letter); }

예 2: 단어를 문자로 나누기

 let arrFruits = ['apple', 'orange', 'banana']; for (let [firstLetter, ...restOfTheWord] of arrFruits) { // Create a shallow copy using the spread operator let [lastLetter] = [...restOfTheWord].reverse(); console.log(firstLetter, lastLetter, restOfTheWord); }

예 3: keyvalue 사용한 루프

 // let arrSimple = ['a', 'b', 'c']; // Instead of keeping an index in `i` as per example `for(let i = 0 ; i<arrSimple.length;i++)` // this example will use a multi-dimensional array of the following format type: // `arrWithIndex: [number, string][]` let arrWithIndex = [ [0, 'a'], [1, 'b'], [2, 'c'], ]; // Same thing can be achieved using `.map` method // let arrWithIndex = arrSimple.map((i, idx) => [idx, i]); // Same thing can be achieved using `Object.entries` // NOTE: `Object.entries` method doesn't work on Internet Explorer unless it's polyfilled // let arrWithIndex = Object.entries(arrSimple); for (let [key, value] of arrWithIndex) { console.log(key, value); }

예 4: 객체 속성을 인라인으로 가져오기

 let arrWithObjects = [{ name: 'Jon', age: 32 }, { name: 'Elise', age: 33 } ]; for (let { name, age: aliasForAge } of arrWithObjects) { console.log(name, aliasForAge); }

예 5: 필요한 항목의 심층 객체 속성 가져오기

 let arrWithObjectsWithArr = [{ name: 'Jon', age: 32, tags: ['driver', 'chef', 'jogger'] }, { name: 'Elise', age: 33, tags: ['best chef', 'singer', 'dancer'] } ]; for (let { name, tags: [firstItemFromTags, ...restOfTags] } of arrWithObjectsWithArr) { console.log(name, firstItemFromTags, restOfTags); }

예 6: 예 3 은 .forEach와 함께 사용 .forEach

 let arrWithIndex = [ [0, 'a'], [1, 'b'], [2, 'c'], ]; // Not to be confused here, `forEachIndex` is the real index // `mappedIndex` was created by "another user", so you can't really trust it arrWithIndex.forEach(([mappedIndex, item], forEachIndex) => { console.log(forEachIndex, mappedIndex, item); });

예 7: 예 4 는 .forEach와 함께 사용 .forEach

 let arrWithObjects = [{ name: 'Jon', age: 32 }, { name: 'Elise', age: 33 } ]; // NOTE: Destructuring objects while using shorthand functions // are required to be surrounded by parentheses arrWithObjects.forEach( ({ name, age: aliasForAge }) => { console.log(name, aliasForAge) });

예 8: 예 5 는 .forEach와 함께 사용 .forEach

 let arrWithObjectsWithArr = [{ name: 'Jon', age: 32, tags: ['driver', 'chef', 'jogger'] }, { name: 'Elise', age: 33, tags: ['best chef', 'singer', 'dancer'] } ]; arrWithObjectsWithArr.forEach(({ name, tags: [firstItemFromTags, ...restOfTags] }) => { console.log(name, firstItemFromTags, restOfTags); });


darklightcode

성능

오늘(2019-12-18) 저는 macOS v10.13.6 (High Sierra), Chrome v 79.0, Safari v13.0.4 및 Firefox v71.0(64비트)에서 테스트를 수행합니다 . 이점은 작지만 코드 복잡성이 증가하기 때문에 일반적으로 코드에 도입할 가치가 없습니다.

  • for i ( Aa )는 모든 브라우저에서 빠른 코드를 작성하는 좋은 선택인 것 같습니다.

  • for-of ( Ad )와 같은 다른 솔루션은 모두 그룹 C에 있습니다. ... 일반적으로 Aa 보다 2 - 10배(이상) 느리지만 작은 배열의 경우 증가를 위해 사용하는 것이 좋습니다. 코드 명확성.

  • n ( Ab, Bb, Be )에 캐시된 루프가 더 빠를 때도 있고 그렇지 않을 때도 있습니다. 아마도 컴파일러는 이 상황을 자동으로 감지하고 캐싱을 도입할 것입니다. 캐시된 버전과 캐시되지 않은 버전( Aa, Ba, Bd ) 간의 속도 차이는 약 1%이므로 도입 n미세 최적화인 것처럼 보입니다.

  • 루프가 마지막 배열 요소( Ac, Bc i-- like 솔루션은 일반적으로 순방향 솔루션보다 ~30% 느립니다. 아마도 그 이유는 CPU 메모리 캐시 작동 방식 때문일 것입니다. 순방향 메모리 읽기는 CPU에 더 적합합니다. 캐싱). 이러한 솔루션을 사용하지 않는 것이 좋습니다.

세부

테스트에서 배열 요소의 합을 계산합니다. 나는 작은 배열(10개 요소)과 큰 배열(1M 요소)에 대한 테스트를 수행하고 세 그룹으로 나눕니다.

  • A - for 시험
  • B - 테스트 while
  • C - 기타/대체 방법

 let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; //let arr = Array.from(Array(1000000), (x, i) => i%10); function Aa(a, s=0) { for(let i=0; i<a.length; i++) { s += a[i]; } console.log('Aa=', s); } function Ab(a, s=0) { let n = a.length; for(let i=0; i<n; i++) { s += a[i]; } console.log('Ab=', s); } function Ac(a, s=0) { for(let i=a.length; i--;) { s += a[i]; } console.log('Ac=', s); } function Ad(a, s=0) { for(let x of a) { s += x; } console.log('Ad=', s); } function Ae(a, s=0) { for(let i in a) if (a.hasOwnProperty(i)) { s += a[i]; } console.log('Ae=', s); } function Ba(a, s=0) { let i = -1; while(++i < a.length) { s+= a[i]; } console.log('Ba=', s); } function Bb(a, s=0) { let i = -1; let n = a.length; while(++i < n) { s+= a[i]; } console.log('Bb=', s); } function Bc(a, s=0) { let i = a.length; while(i--) { s += a[i]; } console.log('Bc=', s); } function Bd(a, s=0) { let i = 0; do { s+= a[i] } while (++i < a.length); console.log('Bd=', s); } function Be(a, s=0) { let i = 0; let n = a.length; do { s += a[i] } while (++i < n); console.log('Be=', s); } function Bf(a, s=0) { const it = a.values(); let e; while (!(e = it.next()).done) { s+= e.value; } console.log('Bf=', s); } function Ca(a, s=0) { a.map(x => { s+=x }); console.log('Ca=', s); } function Cb(a, s=0) { a.forEach(x => { s+=x }); console.log('Cb=', s); } function Cc(a, s=0) { a.every(x => (s += x, 1)); console.log('Cc=', s); } function Cd(a, s=0) { a.filter(x => { s+=x }); console.log('Cd=',s); } function Ce(a, s=0) { a.reduce((z, c) => { s+=c }, 0); console.log('Ce=', s); } function Cf(a, s=0) { a.reduceRight((z, c) => { s += c }, 0); console.log('Cf=', s); } function Cg(a, s=0) { a.some(x => { s += x } ); console.log('Cg=', s); } function Ch(a, s=0) { Array.from(a, x=> s += x); console.log('Cc=', s); } Aa(arr); Ab(arr); Ac(arr); Ad(arr); Ae(arr); Ba(arr); Bb(arr); Bc(arr); Bd(arr); Be(arr); Bf(arr); Ca(arr); Cb(arr); Cc(arr); Cd(arr); Ce(arr); Cf(arr); Cg(arr); Ch(arr);
 <p style="color: red">This snippets only PRESENTS code used for benchmark - it not perform test itself</p>

브라우저 간 결과

테스트된 모든 브라우저에 대한 결과

여기에 이미지 설명 입력 브라우저**

10개의 요소가 있는 배열

Chrome에 대한 결과입니다. 여기 에서 컴퓨터에서 테스트를 수행할 수 있습니다.

여기에 이미지 설명 입력

1,000,000개의 요소가 있는 배열

Chrome에 대한 결과입니다. 여기에서 컴퓨터에서 테스트를 수행할 수 있습니다.

여기에 이미지 설명 입력


Kamil Kiełczewski

귀하의 아이디어에 가장 가까운 방법은 배열의 각 요소에 대해 실행될 클로저 함수를 허용하는 Array.forEach()

 myArray.forEach( (item) => { // Do something console.log(item); } );

또 다른 실행 가능한 방법은 Array.map() 을 사용하는 것입니다. 그러나 반환하는 모든 값을 가져와 다음과 같이 새 배열에 반환합니다(기본적으로 각 요소를 새 배열로 매핑).

 var myArray = [1, 2, 3]; myArray = myArray.map( (item) => { return item + 1; } ); console.log(myArray); // [2, 3, 4]

Ante Jablan Adamović

람다 구문은 일반적으로 Internet Explorer 10 이하에서 작동하지 않습니다.

나는 보통 사용한다

 [].forEach.call(arrayName,function(value,index){ console.log("value of the looped element" + value); console.log("index of the looped element" + index); });

jQuery 이고 이미 jQuery 파일을 실행 중인 경우 인덱스 및 값 매개변수의 위치를 바꿔야 합니다.

 $("#ul>li").each(function(**index, value**){ console.log("value of the looped element" + value); console.log("index of the looped element" + index); });

Murtuza Husain

다음과 같이 forEach를 호출할 수 있습니다.

forEach 는 제공한 배열을 반복하고 각 반복에 대해 해당 반복의 값을 보유하는 element 인덱스가 필요한 경우 forEach에 대한 콜백 함수의 두 번째 매개변수로 i 를 전달하여 현재 인덱스를 가져올 수 있습니다.

Foreach는 기본적으로 다른 함수를 매개변수로 사용하는 고차 함수입니다.

 let theArray= [1,3,2]; theArray.forEach((element) => { // Use the element of the array console.log(element) }

산출:

 1 3 2

다음과 같이 배열을 반복할 수도 있습니다.

 for (let i=0; i<theArray.length; i++) { console.log(i); // i will have the value of each index }

Nouman Dilshad

새로 업데이트된 기능인 ECMAScript 6(ES6) 및 ECMAScript 2015에 따라 루프와 함께 다음 옵션을 사용할 수 있습니다.

루프를 위해

 for(var i = 0; i < 5; i++){ console.log(i); } // Output: 0,1,2,3,4

for...in 루프

 let obj = {"a":1, "b":2} for(let k in obj){ console.log(k) } // Output: a,b

Array.forEach()

 let array = [1,2,3,4] array.forEach((x) => { console.log(x); }) // Output: 1,2,3,4

for...of 루프

 let array = [1,2,3,4] for(let x of array){ console.log(x); } // Output: 1,2,3,4

동안 루프

 let x = 0 while(x < 5){ console.log(x) x++ } // Output: 1,2,3,4

... 동안 루프

 let x = 0 do{ console.log(x) x++ }while(x < 5) // Output: 1,2,3,4

ankitkanojia

요약:

배열을 반복할 때 종종 다음 목표 중 하나를 달성하기를 원합니다.

  1. 배열을 반복하고 새 배열을 만들고 싶습니다.

    Array.prototype.map

  2. 배열을 반복하고 새 배열을 만들지 않으려고 합니다.

    Array.prototype.forEach

    for..of 루프

JavaScript에는 이 두 가지 목표를 모두 달성하는 여러 가지 방법이 있습니다. 그러나 일부는 다른 것보다 더 편리합니다. 아래에서 JavaScript에서 배열 반복을 수행하기 위해 일반적으로 사용되는 몇 가지 방법(가장 편리한 IMO)을 찾을 수 있습니다.

새 배열 생성: Map

map() 은 배열의 모든 요소를 변환한 다음 배열 Array.prototype 에 있는 함수입니다. map() 은 콜백 함수를 인수로 사용하며 다음과 같은 방식으로 작동합니다.

 let arr = [1, 2, 3, 4, 5]; let newArr = arr.map((element, index, array) => { return element * 2; }) console.log(arr); console.log(newArr);

map() 에 인수로 전달한 콜백은 모든 요소에 대해 실행됩니다. 그런 다음 원래 배열과 길이가 같은 배열이 반환됩니다. map() 인수로 전달된 콜백 함수에 의해 변환됩니다.

사이의 뚜렷한 차이 map 와 같은 다른 루프 메커니즘 forEachfor..of 루프 즉 map 새로운 배열과 잎 (같은 생각에 당신이 명시 적으로 조작하는 경우를 제외하고 그대로 기존의 배열 반환 splice ).

또한 map 함수의 콜백은 현재 반복의 인덱스 번호를 두 번째 인수로 제공합니다. 또한 세 번째 인수는 map 이 호출된 배열을 제공합니까? 때때로 이러한 속성은 매우 유용할 수 있습니다.

forEach 사용한 루프

forEach 는 콜백 함수를 인수로 취하는 Array.prototype 그런 다음 배열의 모든 요소에 대해 이 콜백 함수를 실행합니다. map() 함수와 달리 forEach 함수는 아무 것도 반환하지 않습니다( undefined ). 예를 들어:

 let arr = [1, 2, 3, 4, 5]; arr.forEach((element, index, array) => { console.log(element * 2); if (index === 4) { console.log(array) } // index, and oldArray are provided as 2nd and 3th argument by the callback }) console.log(arr);

map 함수와 마찬가지로 forEach 콜백은 현재 반복의 인덱스 번호를 두 번째 인수로 제공합니다. 또한 세 번째 인수는 forEach 가 호출된 배열을 제공합니까?

for..of를 사용하여 요소를 for..of

for..of 루프는 배열의 모든 요소(또는 다른 반복 가능한 객체)를 반복합니다. 다음과 같은 방식으로 작동합니다.

 let arr = [1, 2, 3, 4, 5]; for(let element of arr) { console.log(element * 2); }

위의 예에서 element는 배열 element arr 은 루프하려는 배열입니다. name element 는 임의적이며 'el'과 같은 다른 이름이나 적용 가능한 경우 더 선언적인 이름을 선택할 수 있습니다.

for..in 루프와 for..of 루프를 혼동하지 마십시오. for..in 은 배열의 모든 열거 가능한 속성을 for..of 루프는 배열 요소만 반복합니다. 예를 들어:

 let arr = [1, 2, 3, 4, 5]; arr.foo = 'foo'; for(let element of arr) { console.log(element); } for(let element in arr) { console.log(element); }


Willem van der Veen

forEach() 를 사용하려면 다음과 같이 보일 것입니다.

 theArray.forEach ( element => { console.log(element); });

for() 를 사용하려면 다음과 같이 보일 것입니다.

 for(let idx = 0; idx < theArray.length; idx++){ let element = theArray[idx]; console.log(element); }

Harunur Rashid

화살표 함수를 사용하여 객체 배열을 반복하려면 다음을 수행하십시오.

 let arr = [{name:'john', age:50}, {name:'clark', age:19}, {name:'mohan', age:26}]; arr.forEach((person)=>{ console.log('I am ' + person.name + ' and I am ' + person.age + ' old'); })


subhashish negi

대규모 배열이 있는 경우 효율성을 얻기 iterators 반복자는 특정 JavaScript 컬렉션(예: Map , Set , String , Array )의 속성입니다. 심지어 for..of는 for..of iterator 를 사용합니다.

반복자는 목록의 항목을 스트림인 것처럼 한 번에 하나씩 사용할 수 있도록 하여 효율성을 향상시킵니다. iterator를 특별하게 만드는 것은 컬렉션을 순회하는 방법입니다. 다른 루프는 반복하기 위해 전체 컬렉션을 앞에 로드해야 하지만 반복자는 컬렉션의 현재 위치만 알면 됩니다.

next 메소드를 호출하여 현재 항목에 액세스합니다. 다음 메서드는 현재 항목 value 과 컬렉션의 끝에 도달했을 때를 나타내는 boolean 다음은 배열에서 반복자를 생성하는 예입니다.

다음과 같이 values() 메서드를 사용하여 일반 배열을 iterator로 변환합니다.

 const myArr = [2,3,4] let it = myArr.values(); console.log(it.next()); console.log(it.next()); console.log(it.next()); console.log(it.next());

다음과 같이 Symbol.iterator 사용하여 일반 배열을 iterator로 변환할 수도 있습니다.

 const myArr = [2,3,4] let it = myArr[Symbol.iterator](); console.log(it.next()); console.log(it.next()); console.log(it.next()); console.log(it.next());

다음과 같이 arrayiterator 변환할 수도 있습니다.

 let myArr = [8, 10, 12]; function makeIterator(array) { var nextIndex = 0; return { next: function() { return nextIndex < array.length ? {value: array[nextIndex++], done: false} : {done: true}; } }; }; var it = makeIterator(myArr); console.log(it.next().value); // {value: 8, done: false} console.log(it.next().value); // {value: 10, done: false} console.log(it.next().value); // {value: 12, done: false} console.log(it.next().value); // {value: undefined, done: true}

참고 :

  • 반복자는 본질적으로 소진 가능합니다.
  • 객체는 기본적으로 iterable 할 수 없습니다. 값 대신 키로 작동하기 때문에 이 경우 for..in 을 사용하십시오.

여기에서 iteration protocol 에 대한 자세한 내용을 읽을 수 있습니다.


BlackBeard

출처 : 여기를 클릭하세요


출처 : http:www.stackoverflow.com/questions/9329446/for-each-over-an-array-in-javascript

반응형