JavaScript를 사용하여 배열의 모든 항목을 반복하는 방법은 무엇입니까?
나는 이것이 다음과 같다고 생각했다.
forEach(instance in theArray)
theArray내 배열은 어디에 있지만 이것은 잘못된 것 같습니다.
i < len하고 i++오히려 인터프리터보다는, 엔진에 의해 수행 할 수 있습니다.)
JavaScript를 사용하여 배열의 모든 항목을 반복하는 방법은 무엇입니까?
나는 이것이 다음과 같다고 생각했다.
forEach(instance in theArray)
theArray내 배열은 어디에 있지만 이것은 잘못된 것 같습니다.
i < len하고 i++오히려 인터프리터보다는, 엔진에 의해 수행 할 수 있습니다.)
답변:
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 +)세부:
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같지만 오름차순이 아닌 내림차순으로 작동)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
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에게 요청합니다 .)
물론 인라인 코드에서는 그렇게하지 않을 것입니다. 유틸리티 함수를 작성합니다. 혹시:
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 와 달리 항목을 방문하는 순서는 색인의 숫자 순서입니다.
때로는 반복자를 명시 적으로 사용하고 싶을 수도 있습니다 . 그것보다 훨씬 복잡하지만 그렇게 할 수도 있습니다 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-in
for-in배열과 동일한 보호 장치를 사용하면 배열과 유사한 객체에서도 작동해야합니다. 위의 # 1에 호스트 제공 개체에 대한 경고가 적용될 수 있습니다.
사용 for-of(이터레이터를 암시 적으로 사용) (ES2015 +)
for-of객체가 제공 하는 반복자를 사용 합니다 (있는 경우). 여기에는 호스트 제공 객체가 포함됩니다. 예를 들어, NodeListfrom querySelectorAll에 대한 스펙이 반복을 지원하도록 업데이트되었습니다. 의 사양 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.from
Array.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]]올바르게하지만 테스트하는 것이 중요합니다.)
.forEach효율적으로 깨지지 않는 것을 추가하고 싶습니다 . 휴식을 수행하려면 예외를 던져야합니다.
some. (나는 forEach또한 침입 을 허용 하고 싶지만, 음, 나에게 묻지 않았다. ;-))
,이후 k=0가 아니라 ;. 프로그래밍은 많은 것들을 기억하십시오. 그중 하나는 세부 사항에주의를 기울입니다 ... :-)
length있으며 방법이 아닙니다. :-)
참고 :이 답변은 절망적 인 구식입니다. 보다 현대적인 접근 방식 은 배열에서 사용 가능한 방법을 살펴보십시오 . 관심있는 방법은 다음과 같습니다.
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입니다.
for(instance in objArray) 올바른 사용법 이 아닌 이유는 무엇입니까? 좀 더 단순 해 보이지만 사용법에 대한 올바른 방법이 아니라고 들었습니다.
var키워드로 여러 변수를 선언 할 수 있습니다 . 세미콜론을 사용했다면 element글로벌 범위에서 선언되었을 것입니다 (또는 JSHint가 프로덕션에 도달하기 전에 소리를 지른 것입니다).
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 분 동안 최적화 될 수 있습니다.array[i]), 그 후 정 루프 위치로 왼쪽으로 이동할 항목을 이동 것이다 I 또는 재 공정 된 I 이었다 번째 항목 오른쪽으로 이동했습니다. 전통적인 for 루프에서는 i 를 처리해야하는 다음 항목을 가리 키도록 업데이트 할 수 있지만 반복 방향을 반대로 바꾸는 것이 더 단순 하고 더 우아한 솔루션 인 경우가 많습니다 .forEach()for ... of루프 포워드해야 할 이유가없는 한 일부 개발자 는 기본적으로 역방향 for 루프 를 사용합니다 .
일반적으로 성능 향상은 미미하지만 비명은 다음과 같습니다.
"목록에있는 모든 항목에이 작업을 수행하면 주문에 신경 쓰지 않습니다!"
그러나입니다 실제로 하지 당신이 때 그 경우 구별하기 때문에, 실제로 의도 신뢰할 수있는 표시 할 순서에 대해주의를, 정말 할 필요성을 역으로 루프. 실제로 ECMAScript를 포함하여 대부분의 언어에서 사용할 수 없지만 "예 : 신경 쓰지 않음"의도를 정확하게 표현하기 위해서는 다른 구문이 필요합니다 forEachUnordered().
순서가 중요하지 않고 효율성 이 문제가되는 경우 (게임 또는 애니메이션 엔진의 가장 안쪽 루프에서) 역방향 for 루프를 이동 패턴으로 사용하는 것이 좋습니다. 기존 코드에서 역 for 루프를 보는 것이 반드시 순서와 관련 이 없다는 것을 의미하지는 않습니다 !
일반적으로 선명도와 안전 이 더 중요한 고급 코드의 경우 이전 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단락 될 수있는 루프를 제공 하기 위해 자체 변형 을 제공합니다.
each수있는 메소드 를 보는 것이 일반적 return false이지만 forEach이 방법으로는 옵션이 아닙니다. 외부 플래그를 사용할 수 있습니다 (예를 들어 if (flag) return;, 나머지 함수 본문의 실행 만 막을 forEach수 있음). 여전히 전체 콜렉션에 대해 계속 반복됩니다.
배열을 반복하려면 표준 3 파트 for루프를 사용하십시오 .
for (var i = 0; i < myArray.length; i++) {
var arrayItem = myArray[i];
}
캐싱 myArray.length또는 반복 하여 일부 성능 최적화를 얻을 수 있습니다 .
length. ;)
,과제를 사용한 후에도 새로운 글로벌이 소개 되지 않으므로 제안은 괜찮습니다 ! 다른 문제로 이것을 혼동했습니다 =. 할당을 사용 하면 새로운 전역 이 만들어 집니다.
var i, length, arrayItem;이 오해를 피하기 위해 루프 전에 선언하는 것이 좋습니다 .
나는 이것이 오래된 게시물이라는 것을 알고 있으며 이미 많은 훌륭한 답변이 있습니다. 좀 더 완전성을 위해 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나쁜 소년을 던져 버릴 수 있습니다.
배열을 비우지 않아도되는 경우 :
var x;
while(x = y.pop()){
alert(x); //do something
}
x의 마지막 값을 포함하고 y배열에서 제거됩니다. 를 사용 shift()하여에서 첫 번째 항목을주고 제거 할 수도 있습니다 y.
[1, 2, undefined, 3].
[1, 2, 0, 3]또는[true, true, false, true]
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
}
);
아마도 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
//!!!
세 가지 구현이 있습니다 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
쉬운 해결책은 이제 underscore.js 라이브러리 를 사용하는 것 입니다. 사용 가능한 경우 each작업을 기본으로 자동 위임하는 등의 유용한 도구를 제공 forEach합니다.
작동 방식 의 CodePen 예제 는 다음과 같습니다.
var arr = ["elemA", "elemB", "elemC"];
_.each(arr, function(elem, index, ar)
{
...
});
Array.prototype.forEach() .for each (variable in object)ECMA-357 (의 일부로서 사용되지 EAX ) 표준.for (variable of object)은 하모니 (ECMAScript 6) 제안의 일부로 사용하는 다음 반복 방법을 설명합니다 .for each네이티브 JavaScript 에는 루프 가 없습니다 . 라이브러리를 사용 하여이 기능을 사용하고 ( Underscore.js 권장 ) 간단한 for루프를 사용할 수 있습니다 .
for (var instance in objects) {
...
}
그러나 더 간단한 for루프 를 사용해야하는 이유가있을 수 있습니다 (스택 오버플로 질문을 참조하십시오. 배열 반복에서“for… in”을 사용하는 것은 왜 그렇게 나쁜 생각입니까? )
var instance;
for (var i=0; i < objects.length; i++) {
var instance = objects[i];
...
}
인덱스가 0에서 시작하는 스파 스가 아닌 목록의 반복자입니다. 이는 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 태그가 녹색으로 변경되었습니다.
문자열을 함수로 사용시주의 사항 : 함수는 컨텍스트 외부에서 작성되며 변수 범위가 지정된 경우에만 사용해야합니다. 그렇지 않으면 범위가 더 직관적 인 함수를 전달하는 것이 좋습니다.
있다 몇 가지 방법 루프 아래로, 자바 스크립트의 배열을 통해 :
대한 - 그건 가장 일반적인 하나 . 루핑을위한 전체 코드 블록
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>
배열의 함수형 프로그래밍에 대한 자세한 내용과 예제는 map, filter and reduce : 블로그 JavaScript 함수형 프로그래밍 블로그를 참조하십시오 .
forEach새로운 기능을 반환하지 않기 때문에 Array(실제로는 아무것도 반환하지 않기 때문에) "기능적"루프가 아닙니다 .
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
내장 기능을 사용하는 어레이에서의 작업에 더 관심이있는 경우.
맵핑 -이 콜백 함수의 결과 새로운 배열을 생성한다. 이 방법은 배열의 요소를 포맷해야 할 때 사용하는 것이 좋습니다.
// 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
filter- 필터는 주어진 함수에 true를 반환하는 요소를 가진 배열을 반환한다는 점을 제외하고는 모든 것과 매우 유사합니다.
// Finding the even numbers
[1,2,3,4,5,6].filter(function(elem){
return (elem % 2 == 0)
});
// Output: [2,4,6]
나는 이것을 역 루프의 구성 과이 구문을 좋아하는 누군가를위한 위의 답변으로 추가하고 싶습니다.
var foo = [object,object,object];
for (var i = foo.length, item; item = foo[--i];) {
console.log(item);
}
장점 :
이것의 이점 : 당신은 이미 다른 줄로 선언 할 필요가없는 것과 같은 첫 번째 참조를 이미 가지고 있습니다. 객체 배열을 통해 루핑 할 때 편리합니다.
단점 :
참조가 거짓-거짓 (정의되지 않은 등) 일 때마다 중단됩니다. 그래도 이점으로 사용할 수 있습니다. 그러나 읽기가 조금 더 어려워 질 것입니다. 또한 브라우저에 따라 원래보다 더 빠르게 작동하도록 "최적화되지"않을 수 있습니다.
ECMAScript를 6 사용 루프 destructuring 과 확산 연산자
스프레드 연산자의 구조화 및 사용은 ECMAScript 6을 처음 사용하는 사람들이 좀 더 사람이 읽을 수 있고 심미적 인 것으로 매우 유용한 것으로 입증되었지만 일부 JavaScript 재향 군인은 지저분한 것으로 간주 할 수 있습니다. 주니어 나 다른 사람들이 유용 할 수 있습니다.
다음 예제는
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 : a key와 반복value
// 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
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 : IS 예 4 와 함께 사용.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 : IS 예 5 와 함께 사용.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);
});
아이디어에 가장 가까운 방법 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]
map배열의 요소를 변경하지 않습니다. 새로운 배열의 항목을 기존 배열의 항목에 적용한 결과이므로 새로운 배열을 반환하기 때문입니다.
다음과 같이 각각을 호출 할 수 있습니다.
forEach제공하는 배열을 반복하고 각 반복마다 반복 element값을 보유합니다. 인덱스가 필요한 경우 iforEach의 콜백 함수에서 두 번째 매개 변수로 as 를 전달하여 현재 인덱스를 얻을 수 있습니다 .
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
}
람다 구문은 일반적으로 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);
});
대규모 배열을 사용 iterators하는 경우 효율성을 높이기 위해 사용해야 합니다. 반복자는 특정 자바 스크립트 컬렉션의 재산입니다 (같은 Map, Set, String, Array). 심지어, for..of사용 iterator후드 아래.
반복자는 목록의 항목을 마치 스트림 인 것처럼 한 번에 하나씩 사용할 수 있도록하여 효율성을 향상시킵니다. 반복자를 특별하게 만드는 것은 콜렉션을 순회하는 방법입니다. 다른 루프는 전체 컬렉션을 반복해서로드해야하며 반복자는 컬렉션의 현재 위치 만 알면됩니다.
반복자의 next메소드를 호출하여 현재 항목에 액세스합니다 . 다음 메소드는 value현재 항목의 를 반환 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과 같이 일반 배열을 반복자로 변환 할 수도 있습니다 .
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을 다음 iterator과 같이 변형 할 수도 있습니다 .
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이 경우 값 대신 키와 작동하므로 사용하십시오 .새로운 업데이트 된 기능 ECMAScript 6 (ES6) 및 ECMAScript 2015에 따라 루프와 함께 다음 옵션을 사용할 수 있습니다.
for 루프
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
while 루프
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
오늘 (2019년 12월 18일) 내에서 테스트를 수행 맥 OS v10.13.6 크롬 V 79.0에, (높은 시에라), 사파리 v13.0.4 및 파이어 폭스 v71.0 (64 비트) - 최적화에 대한 결론 (및 마이크로 최적화 하는 이점은 적지 만 코드 복잡성이 커지기 때문에 일반적으로 코드에 도입 할 가치가 없습니다.
전통적인 for i( Aa )는 모든 브라우저에서 빠른 코드를 작성하는 것이 좋습니다.
그룹 C의for-of ( Ad ) 와 같은 다른 솔루션은 모두 Aa 보다 2-10 배 이상 느리지 만 작은 배열의 경우 코드 선명도를 높이기 위해 사용하는 것이 좋습니다.
n( Ab, Bb, Be )에 캐시 된 배열 길이를 가진 루프 는 때로는 더 빠르며 때로는 그렇지 않습니다. 아마도 컴파일러는 자동으로이 상황을 감지하고 캐싱을 도입합니다. 캐시 된 버전과 캐시되지 않은 버전 ( Aa, Ba, Bd ) 사이의 속도 차이 는 약 1 %이므로 소개 n는 미세 최적화 입니다.
i--루프가 마지막 배열 요소 ( Ac, Bc ) 에서 시작 하는 유사한 솔루션 은 일반적으로 순방향 솔루션보다 ~ 30 % 느립니다. 아마도 CPU 메모리 캐시 작동 방식 일 것입니다. 순방향 메모리 읽기는 CPU 캐싱에 더 적합합니다). 이러한 솔루션을 사용하지 않는 것이 좋습니다.
테스트에서 배열 요소의 합을 계산합니다. 작은 배열 (10 요소)과 큰 배열 (1M 요소)에 대한 테스트를 수행하고 세 그룹으로 나눕니다.
for테스트while테스트크로스 브라우저 결과
모든 테스트 된 브라우저에 대한 결과
10 개의 요소로 구성된 배열
Chrome에 대한 결과. 여기 에서 컴퓨터 에서 테스트를 수행 할 수 있습니다 .
1,000,000 개의 요소로 구성된 배열
배열을 반복 할 때 종종 다음 목표 중 하나를 달성하려고합니다.
배열을 반복하고 새 배열을 만들고 싶습니다.
Array.prototype.map
배열을 반복하고 새 배열을 만들지 않습니다.
Array.prototype.forEach
for..of 고리
JavaScript에는이 두 가지 목표를 달성하는 많은 방법이 있습니다. 그러나 일부는 다른 것보다 편리합니다. 아래에서는 JavaScript에서 배열 반복을 수행하기 위해 일반적으로 사용되는 몇 가지 방법 (가장 편리한 IMO)을 찾을 수 있습니다.
Mapmap()는 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와 같은 다른 루프 메커니즘 forEach과 for..of루프 즉 map반환에게 새로운 배열과 잎을 그대로 이전 배열 (같은 생각에 당신이 명시 적으로 조작하는 경우를 제외하고를 splice).
또한 map함수의 콜백은 현재 반복의 색인 번호를 두 번째 인수로 제공합니다. 또한 세 번째 인수 map는 호출 된 배열을 제공 합니까? 때로는 이러한 속성이 매우 유용 할 수 있습니다.
forEachforEach에있는 함수 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..offor..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);
}
forEach단지 뿐만 아니라 찾아 보았습니다for. 언급 한 바와 같이, C #에서이 조금 달랐다, 그것은 :) 저를 혼동