JavaScript의 어레이를 통한 각 기능

JavaScript를 사용하여 어레이 내의 모든 엔트리를 루프하려면 어떻게 해야 합니까?



질문에 대한 답변



TL;DR

  • 당신의 최선의 선택은 보통

    • a for-of 루프(ES2015+만, specMDN): 심플하고async– 프렌들리
      for (const element of theArray) {
      // ...use `element`... } 
    • forEach (ES5+ 한정, specMDN)(또는 그 친척)some기타) – 없음 async– 프렌들리 (상세 참조)
      theArray.forEach(element => {
      // ...use `element`... }); 
    • 단순한 구식for루프 –async– 프렌들리
      for (let index = 0; index < theArray.length; ++index) {
      const element = theArray[index];
      // ...use `element`... } 
    • (표준) for-in 안전장치 포함 –async– 프렌들리
      for (const propertyName in theArray) {
      if (/*...is an array element property (see below)...*/) {
      const element = theArray[propertyName];
      // ...use `element`...
      } } 
  • 몇 가지 간단한 “하지 마세요”:

    • 안전장치와 함께 사용하거나 적어도 왜 물릴 수 있는지 알고 있지 않는 한 사용하지 마십시오.
    • 반환값을 사용하지 않는 경우에는 사용하지 마십시오.
      (슬프게도 저 밖에는map[spec / MDN ]와 같이forEach하지만 블로그에 글을 쓰고 있는 것은 그런 목적이 아닙니다.생성된 어레이를 사용하지 않는 경우 사용하지 마십시오.map.)
    • 콜백이 비동기적으로 동작하고 있는 경우에, 를 사용하지 말아 주세요.forEach그 일이 끝날 때까지 기다리다

하지만 더 많은 것을 탐험하고, 읽을 것이 있다


JavaScript에는 어레이 및 어레이와 같은 오브젝트를 루프하기 위한 강력한 시멘틱스가 있습니다.답을 두 부분으로 나누었습니다.정규 어레이를 위한 옵션 및 어레이와 비슷한 것(예:arguments오브젝트, 기타 반복 가능한 오브젝트(ES2015+), DOM 컬렉션 등입니다.

그럼 다음 옵션을 살펴보겠습니다.

실제 어레이용

5가지 옵션이 있습니다(기본적으로 2가지 옵션은 영구적으로 지원되며, 1가지 옵션은 ECMAScript 5 [“ES5”]에 추가되었으며, 2가지 옵션은 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에 반복기와 반복가능성을 추가하였습니다.어레이는 반복할 수 있습니다(스트링도 마찬가지입니다).MapSets 및 DOM 컬렉션 및 목록도 나중에 확인할 수 있습니다).반복 가능한 개체는 해당 값의 반복자를 제공합니다.새로운for-of스테이트먼트는 반복자에 의해 반환된 값을 루프합니다.

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

그것보다 더 간단할 순 없어!아래에서는 어레이에서 반복기를 가져와 반복기가 반환하는 값을 루프합니다.어레이에 의해 제공되는 반복기는 어레이 요소의 값을 처음부터 끝까지 제공합니다.

주의:element각 루프 반복으로 범위가 지정됩니다.element루프 본체 외부에 존재하지 않기 때문에 루프가 종료된 후에는 실패합니다.

이론상으로는for-of루프는 여러 함수 호출을 수반합니다(하나는 반복기를 얻기 위해, 이제1개는 반복기에서 각 값을 얻기 위해).그것이 사실일지라도 걱정할 것 없다. 함수 호출은 최신 JavaScript 엔진에서 매우 저렴하다.forEach[아래] 자세히 알아볼 때까지요.또한 JavaScript 엔진은 어레이 등의 네이티브 반복기를 처리할 때 이러한 호출을 (퍼포먼스 크리티컬 코드로) 최적화합니다.

for-of완전히async-친절합니다.루프 본체의 작업을 (병행이 아닌) 직렬로 수행해야 하는 경우,await루프 바디는 약속이 정착될 때까지 기다린 후 계속 진행합니다.다음은 어리석은 예입니다.

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

각 단어 앞에 지연이 있는 단어가 표시되는 것에 주의해 주세요.

코딩 스타일의 문제지만for-of반복할 수 있는 것을 반복할 때 가장 먼저 손을 뻗는다.

2. 사용forEach및 관련

모호한 현대 환경(IE8이 아닌)에서도ArrayES5에 의해 추가된 기능을 사용하여forEach (specMDN) 동기 코드만 취급하는 경우(또는 루프 중에 비동기 프로세스가 완료될 때까지 기다릴 필요가 없음):

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

forEach콜백 함수와 옵션으로 콜백함수로서 사용하는 값을 받아들입니다.this콜백(상기 미사용)을 호출할 때 사용합니다.콜백은 배열 내의 각 요소에 대해 호출되며, 순서대로 스퍼스 배열 내의 존재하지 않는 요소를 건너뜁니다.위의 1개의 파라미터만 사용했는데 콜백은 다음 3개의 인수를 사용하여 호출됩니다.해당 반복 요소, 해당 요소의 인덱스 및 반복 중인 배열에 대한 참조입니다(함수에 아직 해당 요소가 없는 경우).

맘에 들다for-of,forEach이 경우 인덱스와 값 변수를 포함하는 범위에서 선언할 필요가 없다는 장점이 있습니다.이 경우 이러한 변수는 반복 함수에 대한 인수로 제공되며 해당 반복에만 적합한 범위가 지정됩니다.

와는 달리for-of,forEach이해할 수 없는 단점이 있다async기능 및await를 사용하는 경우async콜백으로서 기능합니다.forEach계속하기 전에 해당 함수의 약속이 안정되기를 기다리지 않습니다.여기 있습니다.async에서 예시하다.for-of사용.forEach대신 – 초기 지연이 발생하지만 모든 텍스트가 대기하지 않고 바로 나타납니다.

function delay(ms) {
return new Promise(resolve => {
setTimeout(resolve, ms);
}); }
async function showSlowly(messages) {
// INCORRECT, doesn't wait before continuing,
// doesn't handle promise rejections
messages.forEach(async message => {
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 (specMDN) – 콜백이 처음 가짜 값을 반환했을 때 루프를 정지합니다.
  • some (specMDN): 콜백이 처음 truthy 값을 반환했을 때 루프를 정지합니다.
  • filter (specMDN) – 콜백이 truthy 값을 반환하는 요소를 포함한 새로운 배열을 만듭니다.콜백이 반환하지 않는 배열을 제외합니다.
  • map (specMDN): 콜백에 의해 반환된 값에서 새로운 배열을 만듭니다.
  • reduce (specMDN): 콜백을 반복하여 콜백을 호출하고 이전 값을 전달함으로써 값을 작성합니다.자세한 내용은 사양을 참조하십시오.
  • reduceRight (spec MDN) – 유사reduce단, 오름차순이 아닌 내림차순으로 동작합니다.

와 마찬가지로forEach를 사용하는 경우,async콜백으로서 기능합니다.이들 중 어느 것도 함수의 약속이 정착될 때까지 기다리지 않습니다.즉, 다음과 같습니다.

  • 의 사용방법asyncfunction callback은 적절하지 않습니다.every,some,그리고.filter왜냐하면 그들은 돌아온 약속을 진부한 가치인 것처럼 취급할 것이기 때문이다; 그들은 약속이 정착되기를 기다리지 않고 이행 가치를 사용한다.
  • 의 사용방법async함수 콜백은 대부분의 경우 에 적합합니다.map만약 어떤 것의 배열을 약속의 배열로 바꾸는 것이 목표라면, 아마도 약속 조합 함수(Promise.all , , , ) 중 하나에 전달하기 위해서입니다.
  • 의 사용방법async함수 콜백은 거의 적절하지 않습니다.reduce또는reduceRight콜백은 항상 약속을 반환하기 때문입니다.하지만 약속의 사슬을 만드는 사자성어가 있습니다.reduce(const promise = array.reduce((p, element) => p.then(/*...something using `element`...*/));). 단, 보통 이 경우,for-of또는for에 고리를 틀다.async기능이 명확해지고 디버깅이 쉬워집니다.

3. 심플한 것을 사용하다for고리

때로는 예전 방식이 가장 좋습니다.

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

루프 중에 어레이의 길이가 변경되지 않고 퍼포먼스에 매우 민감한 코드일 경우 앞에 있는 길이를 파악하는 것이 약간 더 복잡할 수 있습니다.

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

역방향 카운트:

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

그러나 최신 JavaScript 엔진에서는 마지막 한 조각의 힘을 아껴야 하는 경우는 드물다.

ES2015 이전에는 루프 변수가 포함 범위 내에 존재해야 했습니다.var에는 기능 수준의 범위만 있고 블록 수준의 범위는 없습니다.하지만 위의 예에서 보셨듯이let의 범위 내에서for루프에만 변수를 적용합니다.그리고 그렇게 하면index각 루프 반복에 대해 변수가 재생성됩니다.즉, 루프 본체에 작성된 폐쇄는 다음 각 루프 본체에 대한 참조를 유지합니다.index이 특정 반복을 통해 오래된 “루프 내 오류” 문제가 해결됩니다.

// (The `NodeList` from `querySelectorAll` is array-like) 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>

위의 경우 첫 번째를 클릭하면 “인덱스: 0″이 표시되고 마지막을 클릭하면 “인덱스: 4″가 표시됩니다.를 사용하는 경우는, 이 조작은 동작하지 않습니다.var대신let(“Index is: 5″는 항상 표시됩니다).

맘에 들다for-of,for에서는 루프가 잘 기능한다async기능들.이 예에서는, 다음의 예에 대해, Ethernet의for루프:

function delay(ms) {
return new Promise(resolve => {
setTimeout(resolve, ms);
}); }
async function showSlowly(messages) {
for (let i = 0; i < messages.length; ++i) {
const message = messages[i];
await delay(400);
console.log(message);
} }
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 (Object.hasOwn(a, name) &&
// These checks are
/^0$ ^[1-9]d*$/.test(name) &&
// explained
name <= 4294967294

// below
) {
const element = a[name];
console.log(a[name]);
} }

다음의 3개의 체크에 주의해 주세요.

  1. 오브젝트가 그 이름의 독자적인 속성을 가지고 있는 것(프로토타입에서 상속하는 것이 아닙니다).이 체크는 다음과 같이 작성되는 경우가 많습니다.a.hasOwnProperty(name)ES2022는 어느 쪽이 신뢰성이 높은지를 추가했습니다).

  2. 이름이 모두 10진수(예를 들어 과학적 표기가 아닌 일반 문자열 형식)일 것.

  3. 숫자로 강제되었을 때 이름의 값은 <= 2^32 – 2(4,294,967,294)입니다.그 번호는 어디서 온 거죠?사양에서 어레이 인덱스의 정의의 일부입니다.다른 숫자(정수가 아닌 숫자, 음수, 2^32 – 2보다 큰 숫자)는 배열 색인이 아닙니다.2^32 – 2인 이유는 가장 큰 인덱스 값이 어레이의 최대값인 2^32 – 1보다 1 낮기 때문입니다.length가질 수 있습니다.(예를 들어 배열의 길이는 32비트 부호 없는 정수에 들어갑니다.)

…하지만, 대부분의 코드에서는,hasOwnProperty확인.

물론 인라인 코드에서는 그렇지 않습니다.효용함수를 쓰겠죠아마도:

// 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"; a.b = "bee";
sparseEach(a, (value, index) => {
console.log("Value at " + index + " is " + value); });

맘에 들다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)) { // Almost always this is the only check people do
 const message = messages[name];
 await delay(400);
 console.log(message);
}
} }
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) {
const element = entry.value;
console.log(element); }

반복기는 규격의 반복기 정의와 일치하는 개체입니다.그것의.nextmethod는 호출할 때마다 새 결과 개체를 반환합니다.결과 개체에 속성이 있습니다.done완료 여부를 알려주고 재산도 알려주고value해당 반복의 값을 지정합니다.(done선택 사항입니다.false,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);
const element = entry.value;
console.log(element);
} }
showSlowly([
"So", "long", "and", "thanks", "for", "all", "the", "fish!" ]); // `.catch` omitted because we know it never rejects

어레이 라이크 오브젝트의 경우

실제 어레이 외에 어레이와 같은 오브젝트도 있습니다.length모든 이름이 포함된 속성 및 속성: 인스턴스, 인스턴스,arguments오브젝트 등어떻게 그들의 내용을 뒤집어 볼 수 있을까요?

위의 대부분의 옵션 사용

위의 어레이 접근법 중 적어도 일부 또는 대부분 또는 모든 것이 어레이와 같은 오브젝트에 동일하게 적용됩니다.

  1. 사용하다for-of(암묵적으로 반복기 사용)(ES2015+)

    for-of는 오브젝트에 의해 제공되는 반복기를 사용합니다(있는 경우).여기에는 호스트에서 제공한 개체(DOM 컬렉션 및 목록 등)가 포함됩니다.예를 들어.HTMLCollection의 인스턴스getElementsByXYZ메서드 및NodeList의 인스턴스querySelectorAll둘 다 반복을 지원합니다.(이것은 HTML 및 DOM 사양에 의해 매우 미묘하게 정의됩니다.기본적으로, 모든 오브젝트는length인덱스된 액세스는 자동으로 반복 가능합니다.표시는 필요 없습니다.iterable; 반복가능할 뿐만 아니라 지원 가능한 컬렉션에만 사용됩니다.forEach,values,keys,그리고.entries방법들. NodeList하고 있다.HTMLCollection없습니다만, 둘 다 반복할 수 있습니다.)

    다음으로 루프스루 예를 제시하겠습니다.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 (specMDN). (IE8 이전 버전을 취급해야 할 경우 이 답변의 끝에 있는 “호스트 제공 오브젝트용 동굴”을 참조하십시오.단, 최신 브라우저에서는 문제가 되지 않습니다.)

    사용하고 싶다고 가정해 봅시다.forEach에서NodechildNodes수집(그것은, 하나의 것이 되는 것)HTMLCollection에는 없습니다.forEach네이티브)다음과 같이 할 수 있습니다.

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

    (단, 참고:for-ofnode.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 (spec)(MDN)(ES2015+, 그러나 쉽게 폴리필링됨)은 어레이와 같은 개체에서 어레이를 생성하고 선택적으로 매핑 함수를 통해 엔트리를 먼저 전달합니다.그래서:

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

    …를 차지하다NodeList부터querySelectorAll그리고 그것으로 배열을 만듭니다.

    어떤 식으로든 콘텐츠를 매핑하려면 매핑 기능이 편리합니다.예를 들어, 특정 클래스를 가진 요소의 태그 이름 배열을 가져오는 경우:

    // 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]; 

    예를 들어, 예를 들어, v-in-in-in-in-in-in-in-inNodeListspread 구문을 사용하면 다음과 같이 매우 간결해집니다.

    const divs = [...document.querySelectorAll("div")]; 
  3. 를 사용합니다.slice배열법

    어레이의 방식을 사용할 수 있습니다.이 방법은 위에서 설명한 다른 방법이 “의도적으로 범용”이기 때문에 다음과 같이 어레이와 같은 개체와 함께 사용할 수 있습니다.

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

    예를 들어, 예를 들어, v-in-in-in-in-in-in-in-inNodeList진정한 어레이로 만들 수 있습니다.

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

    (IE8 [oouch]를 계속 처리해야 하는 경우,는 실패합니다.IE8에서는 호스트 제공 오브젝트를 다음과 같이 사용할 수 없습니다.this이렇게)

호스트에서 제공한 개체에 대한 경고

사용하시는 경우Array.prototype호스트가 제공하는 어레이와 같은 오브젝트(예를 들어 JavaScript 엔진이 아닌 브라우저에서 제공하는 DOM 컬렉션 등)와 함께 작동하지만 IE8과 같은 오래된 브라우저는 반드시 이러한 방식으로 처리되지 않으므로 이를 지원해야 하는 경우 타깃 환경에서 테스트해야 합니다.다만, 막연한 최신 브라우저에서는 문제가 되지 않습니다.(브라우저 이외의 환경에서는 당연히 환경에 따라 다릅니다.)




주의: 이 답변은 완전히 구식입니다.좀 더 현대적인 접근법에 대해서는 어레이에서 사용할 수 있는 방법을 살펴보십시오.관심 있는 방법은 다음과 같습니다.

  • 각각
  • 지도
  • 필터
  • 지퍼
  • 줄이자
  • 모든
  • 몇개

JavaScript에서 어레이를 반복하는 표준 방법은 vanilla입니다.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-loop은 레거시 브라우저에도 열거됩니다.또는 추가 속성이 다음과 같이 정의되어 있는 경우enumerable.

ECMAScript 5에서는 어레이 프로토타입에 각 메서드가 있지만 레거시 브라우저에서는 지원되지 않습니다.따라서 이를 일관되게 사용하려면 이를 지원하는 환경(예를 들어 서버 측 JavaScript의 경우 Node.js)을 사용하거나 “Polyfill”을 사용해야 합니다.그러나 이 기능을 위한 Polyfill은 사소한 것이며 코드를 읽기 쉽게 해주므로 포함하기에 좋은 Polyfill입니다.




jQuery 라이브러리를 사용하는 경우 각각 jQuery.를 사용할 수 있습니다.

$.each(yourArray, function(index, value) {
// do your stuff here }); 

편집:

질문에 따르면, 사용자는 jquery가 아닌 javascript로 된 코드를 원하기 때문에 편집은

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



루프 백워드

루프에 대한 반대는 여기서 언급할 가치가 있다고 생각합니다.

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

장점:

  • 임시로 선언할 필요는 없습니다.len변수 또는 비교array.length각 반복에 대해, 그 중 하나가 미세한 최적화일 수 있다.
  • 보통 DOM에서 형제자매를 역순으로 삭제하는 이 더 효율적입니다(브라우저는 내부 배열에서 요소의 이동을 줄일 필요가 있습니다).
  • 루프 중에 어레이를 수정하는 경우 인덱스 i 이후(예를 들어 항목을 제거하거나 삽입하는 경우)array[i]포워드 루프는 왼쪽으로 이동한 항목을 건너뛰거나 오른쪽으로 이동한 항목을 다시 처리합니다.기존의 for 루프에서는 i를 업데이트하여 처리가 필요한 다음 항목인 1을 가리킬 수 있지만, 단순히 반복 방향을 반대로 하는 것이 더 간단하고 우아한 해결책인 경우가 많습니다.
  • 마찬가지로 중첩된 DOM 요소를 수정하거나 제거할 때 역방향으로 처리하면 오류를 방지할 수 있습니다.예를 들어, 내부 변경은부모 노드의 하위 노드 처리 전 HTML.하위 노드에 도달할 때까지 하위 노드가 DOM에서 분리되며, 상위 노드의 내부 노드가 새로 생성된 하위 노드로 대체됩니다.HTML이 작성되었습니다.
  • 사용 가능한 다른 옵션보다 입력 읽기가 더 짧습니다.비록 졌지만forEach()및 ES6의for ... of.

단점:

  • 항목을 역순으로 처리합니다.결과로부터 새로운 어레이를 작성하거나 화면에 인쇄하는 경우는, 본래의 주문에 대해서 출력이 반대로 됩니다.
  • 순서를 유지하기 위해 첫째 자녀로 반복적으로 형제자매를 DOM에 삽입하는 것은 효율적이지 않습니다.(브라우저는 계속 올바르게 전환해야 합니다.)DOM 노드를 효율적으로 순서대로 작성하려면 정상적으로 루프 포워드 및 추가(및 “문서 조각” 사용)하면 됩니다.
  • 역루프는 후배 개발자에게 혼란을 준다.(관점에 따라서는 장점이라고 생각할 수 있다.)

항상 써야 하나요?

일부 개발자는 루프 포워드를 실행할 정당한 이유가 없는 한 기본적으로 루프에 대해 그 반대의 방법을 사용합니다.

퍼포먼스 향상은 보통 미미하지만 다음과 같은 비명을 지릅니다.

“목록의 모든 항목에 대해 이 작업을 수행하세요. 순서 따위는 상관없습니다!”

그러나 실제로는 신뢰할 수 있는 의도를 나타내는 것은 아닙니다.순서에 신경을 쓰는 경우와 구별할 수 없기 때문에 실제로는 반대로 루프할 필요가 있기 때문입니다.따라서 실제로는 “상관없음” 의도를 정확하게 표현하기 위해 다른 구축이 필요합니다. ECMAScript를 포함한 대부분의 언어에서는 현재 사용할 수 없지만 예를 들어 다음과 같이 호출할 수 있습니다.forEachUnordered().

순서가 중요하지 않고 효율이 걱정되는 경우(게임이나 애니메이션 엔진의 가장 안쪽 루프)에는 루프용 역순을 사용할 수 있습니다.기존 코드에서 루프의 역순서가 확인된다고 해서 순서가 무관한 것은 아닙니다.

Each()에 사용하는 것이 좋습니다.

일반적으로 명확성과 안전성이 중요한 상위 레벨의 코드에 대해서는, 이전에는 루프용의 디폴트 패턴으로서 사용하는 것을 추천했습니다(요즘은 사용하는 것을 선호합니다만).for..of)를 희망하는 이유forEach리버스 루프를 경유하는 것은 다음과 같습니다.

  • 읽기가 더 쉬워요.
  • 내가 블록 내에서 이동하지 않을 것임을 나타냅니다(이것은 항상 오랫동안 숨어 있을 수 있는 놀라움입니다).for그리고.while루프)
  • 폐업할 수 있는 자유로운 기회가 주어집니다.
  • 로컬 변수의 누출 및 외부 변수와의 우발적 충돌(및 변환)을 줄입니다.

그 후, 코드에 역방향의 for 루프가 표시되어 있는 경우는, 좋은 이유(아마도 상기의 이유 중 하나)에 의해서 역방향으로 되어 있는 것을 의미합니다.또한 기존의 Forward for loop을 보면 전환이 발생할 수 있음을 알 수 있습니다.

(의도에 대한 논의가 말이 안 된다면, 당신과 당신의 코드는 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(동료를 위해 거의 사용하지 않습니다.)


어떻게 작동합니까?

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--는 false 값으로 평가됩니다(0이 되는 경우).

    비결은…과 다르다는 것이다--i, 후행선i--연산자 감소i그러나 값이 감소하기 전에 산출됩니다.콘솔은 다음과 같이 나타낼 수 있습니다.

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

    [5, 5, 4]

    그래서 마지막 반복에서, 이전에 1살이었고i--expression은 0으로 변경되지만 실제로는 1(truthy)이 생성되므로 조건이 통과합니다.다음 반복 시i--i가 -1변경되지만 0(false)이 되어 실행이 루프 하단에서 즉시 드롭됩니다.

    기존의 Forwards for loop에서는i++그리고.++i(Douglas Crockford가 지적한 바와 같이) 교환이 가능합니다.그러나 루프에 대해서는 반대로, 우리의 감소는 또한 우리의 조건 표현이기 때문에, 우리는 계속해야 합니다.i--인덱스 0에서 아이템을 처리할지 여부를 확인합니다.


트리비아

어떤 사람들은 뒤에 작은 화살을 그리는 것을 좋아한다.for루프하고 윙크로 끝납니다.

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

WYL에 크레딧이 주어지는 것은 루프를 위한 역의 이점과 공포를 보여준 것입니다.




일부 C-스타일 언어에서는foreach열거를 루프합니다.JavaScript에서는 다음과 같은 루프 구조를 사용합니다.

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이는 calback을 사용하여 어레이 상에서 열거할 때 사용할 수 있습니다(폴리필은 문서에 포함되어 있기 때문에 오래된 브라우저에서도 사용할 수 있습니다).

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

주의할 점은Array.prototype.forEach콜백이 반환되어도 끊어지지 않는다.false.jQueryUnderscore.js는 다음과 같은 자체 버전을 제공합니다.each숏 인터럽트 할 수 있는 루프를 제공합니다.