javascript - 함수 - 자바스크립트 배열끼리 비교




각 배열에 대한 자바 스크립트? (19)

뒤로 루프

역방향 for 루프는 여기에 언급 할 가치가 있다고 생각합니다.

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

장점 :

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

단점 :

  • 항목을 역순으로 처리합니다. 결과에서 새 배열을 만들거나 화면에 내용을 인쇄하는 경우 자연스럽게 원래 순서대로 출력이 반전 됩니다.
  • 순서를 유지하기 위해 형제를 첫 번째 자식으로 DOM에 반복적으로 삽입하는 것은 덜 효율적 입니다. DOM 노드를 효율적이고 순차적으로 생성하려면 보통 전달 및 추가 (그리고 "문서 조각"사용)하기 만하면됩니다.
  • 후진 루프는 중학교 개발자들에게 혼란 스럽 습니다. (귀하의 전망에 따라 이점을 고려할 수도 있습니다.)

나는 항상 그것을 사용해야합니까?

일부 개발자는 앞으로 전달할 좋은 이유가없는 한 기본적으로 reverse for 루프 사용합니다.

성능 향상은 대개 중요하지 않지만 다음과 같이 비명을 지릅니다.

"목록의 모든 항목에이 작업을 수행하면 주문에 신경 쓰지 않습니다!"

그러나 실제로는 의도에 대한 신뢰할 수있는 표시가 아니며 주문에 대해 신경 쓰는 경우와 구분할 수 없으므로 실제로 역순으로 반복 해야 합니다. ECMAScript를 비롯하여 대부분의 언어에서는 현재 사용할 수 없지만 예를 들어 forEachUnordered() 와 같이 호출 할 수있는 "무효"의도를 정확하게 표현하려면 다른 구문이 필요합니다.

순서가 중요하지 않고 효율성 (게임이나 애니메이션 엔진의 가장 안쪽 루프에서)이 중요하다면 reverse for 루프를 이동 패턴으로 사용하는 것이 허용 될 수 있습니다. 기존 코드에서 reverse for 루프를 본다고해서 순서가 관련성 이 없다는 것을 반드시 기억 하지 마십시오 !

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

일반적으로 선명도와 안전성 이 더 중요한 고차원 코드의 경우 기본 패턴으로 Array::forEach 를 사용하는 것이 좋습니다.

  • 읽을 것이 분명합니다.
  • 그것은 블록 내에서 이동하지 않을 것임을 나타냅니다 (항상 forwhile 루프에 숨어있을 가능성이 있습니다).
  • 그것은 당신에게 종결을위한 무료 범위를 제공합니다.
  • 그것은 국소 변수의 누설과 외부 변수의 우발적 인 충돌 (및 돌연변이)을 줄입니다.

그런 다음 코드에서 reverse for 루프를 볼 때, 이는 좋은 이유 (아마도 위에 설명 된 이유 중 하나 일 수 있음)가 바뀌 었다는 힌트입니다. 그리고 전통적인 for for loop를 보면 이동이 발생할 수 있음을 나타낼 수 있습니다.

(의도에 대한 토론이 당신에게 이해가되지 않는다면, 프로그래밍 스타일과 두뇌 에 관한 Crockford의 강연을 보면서 당신과 당신의 코드가 도움이 될 것입니다.)

어떻게 작동합니까?

for (var i = 0; i < array.length; i++) { ... }   // Forwards

for (var i = array.length; i--; )    { ... }   // Reverse

중간 절 (우리가 보통 비교를 보는 곳)과 마지막 절이 비어 있음을 알 수 있습니다 (여기서 우리는 보통 i++ 보았습니다). 즉, i-- 또한 계속을위한 조건 으로 사용된다는 것을 의미합니다. 결정적으로 각 반복 전에 실행되고 검사됩니다.

  • 폭발하지 않고 array.length 에서 어떻게 시작할 수 있습니까?

    왜냐하면 각 반복 전에 먼저 실행 되기 때문에 첫 번째 반복에서 array-out-of-bounds undefined 항목 문제를 피하는 array.length - 1 의 항목에 실제로 액세스하게됩니다.

  • 인덱스 0 이전에 iterating이 중지되지 않는 이유는 무엇입니까?

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

    트릭은 --i 와 달리 후행 i 연산자는 i 감소 i-- 감소 이전 의 값을 산출합니다. 콘솔에서 다음을 입증 할 수 있습니다.

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

    [5, 5, 4]

    따라서 최종 반복에서 나는 이전에 1 이었고 i - expression은 0으로 변경했지만 실제로는 1 (truthy)을 산출하므로 조건이 통과됩니다. 다음 반복에서 i-1을 i 로 변경하지만 0 (거짓)을 생성하므로 실행이 즉시 루프 맨 아래로 빠져 나갑니다.

    전통적인 Forward for for 루프에서 ++++ ++i 는 서로 교환 가능합니다 (Douglas Crockford가 지적했듯이). 그러나 reverse for 루프에서는 감소 값이 조건 식이 i-- 인덱스 0에서 항목을 처리하려면 i-- 사용해야합니다.

하찮은 일

어떤 사람들 for 루프의 반대쪽 for 작은 화살표를 그리고 윙크로 끝내기를 좋아합니다.

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

크레딧은 WYL에서 reverse for 루프의 이점과 공포를 보여주기 위해 사용됩니다.

JavaScript를 사용하여 배열의 모든 항목을 반복하는 방법은 무엇입니까?

나는 그것이 다음과 같다고 생각했다.

forEach(instance in theArray)

어디에 theArray 내 배열이지만 잘못된 것으로 보입니다.


개요:

배열을 반복 할 때 종종 다음 목표 중 하나를 달성 할 수 있습니다.

  1. 우리는 배열을 반복하고 새로운 배열을 생성하고자합니다 :

    Array.prototype.map

  2. 우리는 배열을 반복하고 새로운 배열을 만들지 않기를 원합니다 :

    Array.prototype.forEach

    for..of 고리

JS에서는 이러한 두 가지 목표를 달성하는 여러 가지 방법이 있습니다. 그러나 어떤 것은 다른 것보다 conventient하다. 아래에서 자바 스크립트에서 배열 반복을 수행하기 위해 일반적으로 사용되는 메소드 (가장 conventient 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 함수는 nothing ( 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루프는 배열 (또는 다른 반복 가능한 객체)의 모든 요소를 통해 루프. 그것은 다음과 같은 방식으로 작동합니다 :

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

for(let element of arr) {
  console.log(element * 2);
}

위의 예에서는 element배열 요소 를 나타내며 arr루프를 만들려는 배열입니다. 이름 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);
}


배열을 반복하려면 표준 3 부분 for 루프를 사용하십시오.

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

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


배열을 비우는 것에 신경 쓰지 않는다면 :

var x;

while(x = y.pop()){ 

    alert(x); //do something 

}

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


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

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

ES6부터 :

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

where of는 연관된 oddities를 피하고 다른 언어 infor루프 처럼 작동하게 하고 함수 내에서 루프 내에서 let바인딩 i합니다.

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


TL, DR

  • 안전 장치와 함께 사용하거나 최소한 그것이 왜 당신을 물릴 지 모른다고 생각하지 않는 한 for-in 사용하지 마십시오.
  • 최상의 베팅은 대개

    • for-of 루프 (ES2015 + 만 해당),
    • Array#forEach ( spec | MDN ) (또는 그 친척 some ) (ES5 + 전용),
    • 간단한 구식 for 루프,
    • 또는 안전 장치 for-in 있는 유인물.

그러나 더 많은 것을 탐구하고, 읽으십시오 ...

JavaScript는 배열과 배열과 같은 객체를 통해 루핑하기위한 강력한 의미를가집니다. 저는 대답을 두 부분으로 나누었습니다 : 진짜 배열을위한 옵션 , 단지 배열 과 비슷한 것들, 예를 들어 arguments 객체, 다른 반복 가능한 객체 (ES2015 +), DOM 콜렉션 등과 같은 옵션.

ES2015 옵션을 지금도 ES5 엔진에서 ES2015에서 ES5로 전환하여 사용할 수 있음을 빠르게 알려드립니다. "ES2015 transpilating"/ "ES6 transpiling"검색

자, 우리 옵션을 살펴 보자.

실제 배열의 경우

ECMAScript 5 ( "ES5")에는 현재 가장 널리 지원되는 버전과 ECMAScript 2015 ( "ES2015", "ES6")에 추가 된 세 가지 옵션이 있습니다.

  1. 각 및 관련 (ES5 +)
  2. for 돌이 사용
  3. for-in 올바르게 사용하십시오.
  4. for-of 사용합니다 (암시 적으로 반복자 사용) (ES2015 +).
  5. 반복자를 명시 적으로 사용 (ES2015 +)

세부:

1. 각각의 용도와 관련

ES5 (직접 또는 폴리 폴리을 사용)에 의해 추가 된 Array 기능에 액세스 할 수있는 막연한 현대 환경 (IE8 아님)에서는 forEach ( spec | MDN )를 사용할 수 있습니다.

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

forEach 는 해당 콜백을 호출 할 때 콜백 함수와 선택적 this 값을 사용할 수 있습니다 (위에서 사용하지 않음). 콜백은 배열의 각 항목에 대해 순서대로 나열되어 스파 스 배열에 존재하지 않는 항목을 건너 뜁니다. 위의 인수를 하나만 사용했지만 콜백은 각 항목의 값, 해당 항목의 인덱스 및 반복되는 배열에 대한 참조 (함수에 아직 유용하지 않은 경우에 대비하여) ).

Internet Explorer 8과 같은 오래된 브라우저 (2016 년 9 월에 NetApp이 4 %의 시장 점유율 이상을 기록함)를 지원하지 않는 한, sham을 사용하지 않고 범용 웹 페이지에서 forEach 를 행복하게 사용할 수 있습니다. 더 이상 사용하지 않는 브라우저를 지원해야하는 경우 각 브라우저에서 shimming / polyfilling for eachach를 쉽게 수행 할 수 있습니다 (여러 옵션에서 "es5 shim"을 검색).

forEach 는 인덱싱 및 값 변수를 포함 범위에서 선언 할 필요가 없다는 장점이 있습니다. 즉, 반복 함수에 대한 인수로 제공되므로 잘 정의 된 반복만으로 범위가 지정됩니다.

각 배열 항목에 대한 함수 호출을 만드는 데 드는 런타임 비용이 걱정된다면 그렇게하지 마십시오. blog.niftysnippets.org/2012/02/foreach-and-runtime-cost.html .

또한 forEach 는 "모두를 통한 루프"기능을 제공하지만 ES5는 다음을 비롯한 여러 가지 유용한 "배열 및 작업 수행 방식"기능을 정의했습니다.

  • every (콜백이 false 리턴하거나 false 반환 할 때 루핑을 중지 함)
  • some (콜백이 true 또는 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]);
}

그러나 최신 자바 스크립트 엔진을 사용하면 마지막 주스를 꺼내야 할 때가 드뭅니다.

ES2015 이상에서는 for 루프에 for 색인 및 값 변수를 로컬로 만들 수 있습니다.

let a = ["a", "b", "c"];
for (let index = 0; index < a.length; ++index) {
    let value = a[index];
}
//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 => {
        alert("Index is: " + index);
    });
}

5 개의 div가있는 경우 첫 번째를 클릭하면 "색인 : 0"을, 마지막을 클릭하면 "색인 : 4"를 얻게됩니다. let 대신에 var 를 사용하면 이것은 작동하지 않습니다 .

3. for-in 올바르게 사용하십시오.

당신은 for-in 을 사용하라는 사람들을 알게 될 것 for-in . 그러나 그것이 for-in 을위한 것이 아닙니다 . for-in 루프는 배열의 인덱스가 아니라 객체열거 가능 속성을 통해 수행됩니다. 주문은 ES2015 (ES6)조차도 보장 되지 않습니다. ES2015는 [[OwnPropertyKeys]] , [[Enumerate]]Object.getOwnPropertyKeys 와 같은 객체를 사용하는 것들을 통해 객체 속성에 대한 순서를 정의하지만 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 are explained
        /^0$|^[1-9]\d*$/.test(key) &&    // and then hidden
        key <= 4294967294                // away below
        ) {
        console.log(a[key]);
    }
}

두 가지 사항을 확인하십시오.

  1. 그 객체는 그 이름으로 자체의 속성을 가진다 (프로토 타입으로부터 상속받은 것이 아님).

  2. 이 키는 일반 문자열 형식의 기본 10 숫자 문자열이며 해당 값은 <= 2 ^ 32 - 2 (4,294,967,294)입니다. 그 번호는 어디서 나왔습니까? 이것은 스펙 의 배열 인덱스 정의의 일부입니다. 다른 수 (정수가 아닌 수, 음수, 2 ^ 32-2보다 큰 수)는 배열 색인이 아닙니다. 2 ^ 32 - 2 인 이유는 배열의 length 가 가질 수있는 최대 값 인 2 ^ 32 - 1 보다 큰 인덱스 값을 하나 낮추기 때문입니다. (예를 들어, 배열의 길이는 32 비트 부호없는 정수에 맞습니다.) (RobG의 소품에서 내 이전 블로그 테스트에 대한 의견을 지적 해주었습니다.

이는 대부분의 배열에서 루프 반복 당 약간의 추가 오버 헤드이지만, 배열이 희박한 경우 실제로 존재하는 항목 만 루프하기 때문에 반복하는 것이 더 효율적인 방법 일 수 있습니다. 예를 들어 위의 배열에 대해 우리는 10,001 번이 아니라 총 세 번 반복합니다 (키 "0" , "10""10000" - 문자열임을 기억하십시오).

이제는 매번 그 내용을 쓰고 싶지 않으므로 이것을 툴킷에 넣을 수 있습니다.

function arrayHasOwnIndex(array, prop) {
    return array.hasOwnProperty(prop) && /^0$|^[1-9]\d*$/.test(prop) && prop <= 4294967294; // 2^32 - 2
}

그리고 나서 우리는 이것을 다음과 같이 사용합니다 :

for (key in a) {
    if (arrayHasOwnIndex(a, key)) {
        console.log(a[key]);
    }
}

또는 "대부분의 경우에 적합합니다"테스트에만 관심이있는 경우이 테스트를 사용할 수 있지만 가까운 경우에는 정확하지 않습니다.

for (key in a) {
    // "Good enough" for most cases
    if (String(parseInt(key, 10)) === key && a.hasOwnProperty(key)) {
        console.log(a[key]);
    }
}

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

ES2015는 반복기 를 JavaScript에 추가 합니다 . 반복자를 사용하는 가장 쉬운 방법은 새로운 for-of 문입니다. 다음과 같이 보입니다.

var val;
var a = ["a", "b", "c"];
for (val of a) {
    console.log(val);
}

산출:

a
b
c

커버 아래에서 배열에서 반복자 를 가져 와서 루프를 통해 값을 가져옵니다. 객체 (배열)에 의해 정의 된 반복자를 사용하고 배열은 반복자가 해당 속성이 아닌 항목을 반복하여 반복하도록 정의하므로 for-in 을 사용하는 것이 문제가되지 않습니다. ES5의 for-in 과 달리 항목을 방문하는 순서는 색인의 숫자 순서입니다.

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

때로는 반복자를 명시 적으로 사용하고자 할 수 있습니다. for-of 보다 훨씬 까다 롭긴하지만 그렇게 할 수도 있습니다. 다음과 같이 보입니다.

var a = ["a", "b", "c"];
var it = a.values();
var entry;
while (!(entry = it.next()).done) {
    console.log(entry.value);
}

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

value 의 의미는 반복자에 따라 다릅니다. 배열은 (최소한) 반복자를 반환하는 세 가지 함수를 지원합니다.

  • values() : 위에 사용 된 값입니다. iterator를 반환합니다. 각 value 은 해당 반복의 배열 항목입니다 (앞의 예제에서 "b" , "b""c" ).
  • keys() : 각각의 value 이 해당 반복의 키인 반복자를 반환합니다 a 위의 예에서는 "0" , "1" , "2" 입니다.
  • entries() : 각 반복자의 [key, value] 형식의 배열 인 각 반복자를 반환합니다.

배열과 같은 객체의 경우

실제 배열과는 달리 length 속성과 숫자 이름을 가진 속성 인 NodeList 인스턴스, arguments 객체 등이 배열과 유사한 객체입니다. 어떻게 내용을 반복합니까?

배열에 대해 위의 옵션 중 하나를 사용하십시오.

배열 접근법 중 적어도 일부, 가능하게는 대부분 또는 모두가 배열과 유사한 객체에 똑같이 잘 적용됩니다.

  1. 각 및 관련 (ES5 +)

    Array.prototype 의 다양한 함수는 "의도적으로 일반"이며 Function#call 또는 Function#apply 를 통해 배열과 유사한 객체에서 일반적으로 사용할 수 Function#apply . 이 답변 끝 부분에 호스트 제공 객체대한주의 사항 이 있지만 드문 문제입니다.

    NodechildNodes 속성에서 forEach 를 사용하려고한다고 가정합니다. 당신이 할거야 :

    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`
    });
    
  2. for 돌이 사용

    분명히 간단한 for 루프가 배열과 같은 객체에 적용됩니다.

  3. for-in 올바르게 사용하십시오.

    for-in 배열과 같은 보호 장치는 배열과 유사한 객체에서도 작동해야합니다. 위 # 1의 호스트 제공 객체에 대한주의 사항이 적용될 수 있습니다.

  4. for-of 사용합니다 (암시 적으로 반복자 사용) (ES2015 +).

    for-of 는 객체가 제공하는 반복자를 사용합니다 (있는 경우). 우리는 다양한 배열과 같은 객체들, 특히 호스트가 제공하는 객체들과 함께 이것이 어떻게 작동 하는지를 알아야 할 것이다. 예를 들어, querySelectorAllNodeList 대한 사양이 반복을 지원하도록 업데이트되었습니다. getElementsByTagNameHTMLCollection 대한 사양이 아닙니다.

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

    # 4를 보면 iterator가 어떻게 작동하는지보아야합니다.

진정한 배열 만들기

다른 경우에는 배열과 같은 객체를 실제 배열로 변환 할 수 있습니다. 그렇게하는 것은 놀랍도록 쉽습니다.

  1. 배열의 slice 메소드 사용

    우리는 배열의 slice 메소드를 사용할 수 있습니다. 위에서 언급 한 다른 메소드는 "의도적으로 일반"이므로 다음과 같이 배열과 같은 객체와 함께 사용할 수 있습니다.

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

    예를 들어 NodeList 를 true 배열로 변환하려면 다음을 수행 할 수 있습니다.

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

    아래 에 호스트 제공 객체에 대한주의 사항을 참조하십시오. 특히 IE8 이하에서는 실패 할 것이므로 호스트 제공 객체를 this 같이 사용할 수는 없습니다.

  2. 확산 구문 사용 ( ... )

    또한이 기능을 지원하는 JavaScript 엔진과 함께 ES2015의 확산 구문 을 사용할 수도 있습니다.

    var trueArray = [...iterableObject];
    

    예를 들어, NodeList 를 확산 구문으로 변환하려면 다음과 같이하면됩니다.

    var divs = [...document.querySelectorAll("div")];
    
  3. Array.from (spec) | (MDN)

    Array.from (ES2015 +, 쉽게 polyfilled)은 배열과 같은 객체에서 배열을 생성합니다. 선택적으로 매핑 함수를 통해 항목을 먼저 전달할 수 있습니다. 그래서:

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

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

Array.prototype 함수를 호스트 제공 배열과 유사한 객체 (JavaScript 목록이 아닌 브라우저에서 제공하는 DOM 목록 및 기타 항목)와 함께 사용하는 경우 대상 환경에서 호스트가 제공하는 객체를 확인하기 위해 반드시 테스트해야합니다 객체가 올바르게 동작합니다. 대부분 (현재) 올바르게 작동 하지만 테스트하는 것이 중요합니다. 그 이유는 여러분이 사용하기를 원하는 대부분의 Array.prototype 메소드는 호스트 제공 객체를 사용하여 추상 [[HasProperty]] 연산에 정직한 답을 제공하기 때문입니다. 이 글을 쓰는 시점에서 브라우저는 매우 훌륭하게 작동하지만, 5.1 사양은 호스트가 제공하는 객체가 정직하지 않을 가능성을 허용했습니다. 이것은 §8.6.2§8.6.2 , 그 섹션의 시작 부분 근처의 큰 테이블 아래의 여러 단락들)에 다음과 같이 쓰여 있습니다 :

호스트 객체는 달리 명시하지 않는 한 어떤 방식 으로든 이러한 내부 메소드를 구현할 수 있습니다. 예를 들어 특정 호스트 객체에 대한 [[Get]][[Put]] 은 실제로 속성 값을 가져 와서 저장하지만 [[HasProperty]] 항상 false를 생성 할 수 있습니다.

(필자는 ES2015 스펙에서 동등한 표현을 찾을 수 없었지만 여전히 그렇습니다.)이 글을 쓰면서 현재의 브라우저에서 일반적인 호스트 제공 배열과 유사한 객체 [ NodeList 인스턴스, 예] do [[HasProperty]] 올바르게 처리해야하지만 테스트하는 것이 중요합니다.)


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

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

let Array = [1,3,2];

theArray.forEach((element)=>{ 
  // use the element of the array
  console.log(element) 
}

요소는 0부터 배열의 길이까지의 각 인덱스의 값을가집니다.

산출:

1    
3    
2

설명 :

forEach는 프로토 타입 클래스입니다. 당신은 또한 thisArray.prototype.forEach (...);

프로토 타입 : https://hackernoon.com/prototypes-in-javascript-5bba2990e04b

다음과 같이 배열을 변경할 수도 있습니다.

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

나는 또한이 구문을 좋아할만한 누군가를 위해 역 루프와 위의 대답의 구성으로 이것을 추가하고 싶다.

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

장점 :

이것에 대한 이점 : 나중에 다른 라인으로 선언 할 필요가없는 첫 번째와 같은 참조가 이미 있습니다. 객체 배열을 반복 할 때 유용합니다.

단점 :

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


배열로 작업하는 ECMAScript5 (Javascript의 버전).

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

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

// Output
// C is the #1 in musical scale
// D is the #2 in musical scale
// E is the #3 in musical scale

경우에, 더 inbuilt 기능을 사용하여 배열 작업에 관심이 많습니다.

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

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

// Output: ['BOB', 'JOE', 'JEN']

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

[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

filter - 필터가 해당 함수에 true를 반환하는 요소가있는 배열을 반환한다는 점을 제외하고는 모두 매우 비슷합니다.

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

// Output: [2,4,6]

희망이 유용 할 것입니다.


이것은 인덱스가 0에서 시작하는 NON-sparse 목록에 대한 반복기입니다.이 인덱스는 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 태그가 녹색으로 변경됩니다.

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


inbuilt에 침입 할 능력이 없습니다 forEach. 실행을 중단하려면 다음 Array#some과 같이 사용하십시오 .

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

이것은 some배열 순서로 실행되는 콜백이 true를 반환하자마자 true를 반환 하기 때문에 작동 합니다. 나머지는 실행을 단락시킵니다. 원래 응답 some 프로토 타입을 참조하십시오some


jQuery 방식을 사용하여 $.map:

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

방대한 배열을 가지고 있다면 iterators효율성을 높이기 위해 사용해야 합니다. 반복자는 (같은 특정 자바 스크립트 컬렉션의 재산 Map, Set, String, Array). 심지어, for...of사용 iterator후드 아래.

반복자는 마치 스트림 인 것처럼 목록의 항목을 한 번에 하나씩 소비함으로써 효율성을 향상시킵니다. 반복기를 특별하게 만드는 것이 컬렉션을 통과하는 방법입니다. 다른 루프는 컬렉션을 반복하기 위해 전체 컬렉션을 앞에로드해야하지만 반복기는 컬렉션의 현재 위치 만 알아야합니다.

이터레이터의 next메소드를 호출하여 현재 항목에 액세스한다 . 다음 메소드는 value현재 항목의 를 리턴 하고 a boolean는 콜렉션의 끝에 도달했을 때를 표시합니다. 다음은 배열에서 반복자를 만드는 예제입니다.

다음 values()과 같은 메소드를 사용하여 일반 배열을 반복자로 변환하십시오 .

    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());

정규병 array을 다음 iterators과 같이 변형 할 수도 있습니다 .

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 here 참조 here .


세 가지 구현이 있습니다 foreach에서 jQuery 다음과 같이가.

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

아마 for(i = 0; i < array.length; i++)루프가 최선의 선택이 아닙니다. 왜? 당신이 가지고있는 경우 :

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

메서드는 from 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
//!!!

아이디어에 가장 가까운 방법 Array.forEach()은 배열의 각 요소에 대해 실행될 clojure 함수 를 사용 하는 것입니다.

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

또 다른 가능한 방법은 Array.map()같은 방식으로 작동하지만 mutates각 요소를 사용하고 다음과 같이 반환하는 것입니다.

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

console.log(myArray); // [2, 3, 4]

var a = ["car", "bus", "truck"]
a.forEach(function(item, index) {
    console.log("Index" + index);
    console.log("Element" + item);
})




iteration