Java에서는 for
다음과 같이 루프를 사용 하여 배열의 객체를 순회 할 수 있습니다 .
String[] myStringArray = {"Hello", "World"};
for (String s : myStringArray)
{
// Do something
}
JavaScript에서도 같은 작업을 수행 할 수 있습니까?
답변
몇 가지 옵션이 있습니다.
1. 순차 for
루프 :
var myStringArray = ["Hello","World"];
var arrayLength = myStringArray.length;
for (var i = 0; i < arrayLength; i++) {
console.log(myStringArray[i]);
//Do something
}
찬성
- 모든 환경에서 작동
- 제어문을 사용
break
하고continue
플로우 할 수 있습니다
단점
- 너무 자세한
- 피할 수 없는
- 일대일 오류가 발생 하기 쉽습니다 (때때로 펜스 포스트 오류 라고도 함 )
2. Array.prototype.forEach
ES5 사양은 많은 유익한 배열 방법 중 하나를 도입했으며 배열 Array.prototype.forEach
을 반복하는 간결한 방법을 제공합니다.
const array = ["one", "two", "three"]
array.forEach(function (item, index) {
console.log(item, index);
});
ES5 사양이 출시 된 시점 (2009 년 12 월)에 거의 10 년이 지난 지금 데스크톱, 서버 및 모바일 환경의 거의 모든 최신 엔진에 의해 구현되었으므로 안전하게 사용할 수 있습니다.
그리고 ES6 화살표 함수 구문을 사용하면 훨씬 간결합니다.
array.forEach(item => console.log(item));
화살표 기능은 고대 플랫폼 (예 : IE11)을 지원할 계획이 아니라면 널리 구현됩니다. 당신은 또한 안전합니다.
찬성
- 매우 짧고 간결합니다.
- 선언적
단점
break
/를 사용할 수 없습니다continue
일반적으로 break
배열 요소를 반복하기 전에 필터링하여 명령형 루프 에서 벗어날 필요성을 대체 할 수 있습니다 . 예를 들면 다음과 같습니다.
array.filter(item => item.condition < 10)
.forEach(item => console.log(item))
당신이 배열을 반복하는 경우 명심 가에서 다른 배열을 구축하기 위해 , 당신은 사용해야을 map
나는 여러 번 있도록이 안티 패턴을 보았다.
안티 패턴 :
const numbers = [1,2,3,4,5], doubled = [];
numbers.forEach((n, i) => { doubled[i] = n * 2 });
지도의 적절한 사용 사례 :
const numbers = [1,2,3,4,5];
const doubled = numbers.map(n => n * 2);
console.log(doubled);
또한 배열을 값 으로 줄이려고 하는 경우 (예를 들어, 숫자 배열을 합산하려는 경우) reduce 메소드를 사용해야합니다 .
안티 패턴 :
const numbers = [1,2,3,4,5];
const sum = 0;
numbers.forEach(num => { sum += num });
Reduce의 적절한 사용 :
const numbers = [1,2,3,4,5];
const sum = numbers.reduce((total, n) => total + n, 0);
console.log(sum);
3. ES6 for-of
진술
ES6 표준은 반복 가능한 객체의 개념을 소개하고 데이터를 순회하기위한 새로운 for...of
구문 인 명령문 을 정의합니다 .
이 문장은 모든 종류의 반복 가능한 객체와 생성기 ( [Symbol.iterator]
속성 이있는 객체 )에서도 작동합니다.
ES6에는 배열 객체가 정의에 따라 내장 이터 러블이므로이 명령문을 사용할 수 있습니다.
let colors = ['red', 'green', 'blue'];
for (const color of colors){
console.log(color);
}
찬성
- 다양한 객체를 반복 할 수 있습니다.
- 일반적인 흐름 제어문을 사용할 수 있습니다 (
break
/continue
)을 . - 직렬 비동기 값을 반복하는 데 유용합니다.
단점
- 이전 브라우저를 대상으로하는 경우 변환 된 출력 결과 가 놀라 울 수 있습니다 .
사용하지 마세요 for...in
@zipcodeman은 for...in
명령문 사용을 제안 하지만 배열 반복을 for-in
피하려면 해당 명령문을 열거해야합니다. 오브젝트 특성 입니다.
다음과 같은 이유로 배열과 같은 객체에 사용해서는 안됩니다.
- 반복 순서는 보장되지 않습니다. 배열 인덱스는 숫자 순서대로 방문 할 수 없습니다.
- 상속 된 속성도 열거됩니다.
두 번째 요점은 예를 들어 Array.prototype
메소드를 포함 오브젝트를 해당 특성도 열거됩니다.
예를 들면 다음과 같습니다.
Array.prototype.foo = "foo!";
var array = ['a', 'b', 'c'];
for (var i in array) {
console.log(array[i]);
}
위의 코드는 콘솔 로그 “a”, “b”, “c”및 “foo!”입니다.
네이티브 프로토 타입 기능 보강 (예 : MooTools)에 크게 의존하는 라이브러리를 사용하는 경우 특히 문제가됩니다.
for-in
문은 내가 이전에이 말한대로 열거 예를 들어, 개체 속성을 :
var obj = {
"a": 1,
"b": 2,
"c": 3
};
for (var prop in obj) {
if (obj.hasOwnProperty(prop)) {
// or if (Object.prototype.hasOwnProperty.call(obj,prop)) for safety...
console.log("prop: " + prop + " value: " + obj[prop])
}
}
위의 예제 hasOwnProperty
에서이 메서드를 사용하면 고유 한 속성 , 즉 개체에 물리적으로있는 속성 만 상속 된 속성 만 열거 할 수 있습니다 .
다음 기사를 읽는 것이 좋습니다.
답변
예, 구현 에 ECMAScript 2015에 도입 된 for
…of
기능 ( “하모니”릴리스)이 포함되어 있다고 가정하면 요즘 꽤 안전한 가정입니다.
다음과 같이 작동합니다.
// REQUIRES ECMASCRIPT 2015+
var s, myStringArray = ["Hello", "World"];
for (s of myStringArray) {
// ... do something with s ...
}
ECMAScript 2015는 블록 범위 변수도 제공하므로 더 좋습니다.
// REQUIRES ECMASCRIPT 2015+
const myStringArray = ["Hello", "World"];
for (const s of myStringArray) {
// ... do something with s ...
}
// s is no longer defined here
( s
반복마다 변수 가 다르지만 const
루프 본문 내에서 수정되지 않는 한 선언 할 수 있습니다 .)
희소 배열에 대한 참고 사항 : JavaScript의 배열은 실제로보고 된만큼 많은 항목을 저장할 수 없습니다 length
. 그보고 된 숫자는 단순히 값이 저장되는 가장 높은 인덱스보다 하나 더 큽니다. 배열이 길이로 표시된 것보다 적은 수의 요소를 보유하면 희소 하다고합니다 . 예를 들어 인덱스 3, 12 및 247에만 항목이있는 배열을 갖는 것이 합법적입니다. 누락 된 요소들, 또는 당신은 실제로 존재하는 요소를 처리 할 수 있습니까? 두 가지 접근 방식에 대한 많은 응용 프로그램이 있습니다. 배열을 사용하는 대상에 따라 다릅니다.length
이 실제로 3 개 값을 저장하고 있지만 이러한 배열은, (248)로보고된다. 다른 인덱스에서 항목에 액세스하려고하면 배열에 undefined
값이 있는 것으로 나타납니다 . 따라서 배열을 “루프 스루”하려는 경우 대답해야 할 질문이 있습니다. 길이와 프로세스로 표시되는 전체 범위를 루핑 하시겠습니까?undefined
for
.. 을 사용하여 배열을 반복 of
하면 루프의 본문이 실행되고 배열에 실제로 존재하지 않는 항목 length
에 undefined
대해 루프 제어 변수가 설정됩니다 . “함께하는 것”코드의 세부 사항에 따라 해당 동작이 원하는 것일 수 있지만 그렇지 않은 경우 다른 방법을 사용해야합니다.
물론, 일부 개발자들은 선택의 여지가 있지만, 때문에 그들은 아직 지원하지 않는 자바 스크립트의 버전을 타겟팅하고 어떤 이유로, 어쨌든 다른 접근 방법을 사용하는 것이 for
… of
.
JavaScript 구현이 ECMAScript 사양 의 이전 버전 (예 : 9 이전의 Internet Explorer 버전을 배제)을 준수 Array#forEach
하는 경우 루프 대신 반복자 메서드를 사용할 수 있습니다 . 이 경우 배열의 각 항목에서 호출 할 함수를 전달합니다.
var myStringArray = [ "Hello", "World" ];
myStringArray.forEach( function(s) {
// ... do something with s ...
} );
달리 for
… of
, .forEach
실제로 어레이에 존재하는 요소의 함수를 호출한다. 세 개의 요소와 길이가 248 인 가상 배열을 전달하면 248 번이 아니라 함수를 세 번만 호출합니다. 또한 누락 된 요소와 실제로 설정된 요소를 구분합니다 undefined
. 후자의 경우 여전히 함수를 호출 undefined
하여 인수로 전달 합니다. 이것이 희소 배열을 처리 .forEach
하는 방법이라면 통역사가 for
…을 지원하더라도 갈 수있는 방법 일 수 있습니다 of
.
모든 버전의 JavaScript 에서 작동하는 마지막 옵션 은 명시적인 계산 루프 입니다. 단순히 0에서 길이보다 1을 작게 세어 카운터를 인덱스로 사용하십시오. 기본 루프는 다음과 같습니다.
var i, s, myStringArray = [ "Hello", "World" ], len = myStringArray.length;
for (i=0; i<len; ++i) {
s = myStringArray[i];
// ... do something with s ...
}
이 방법의 장점 중 하나는 희소 배열을 처리하는 방법을 선택할 수 있다는 것입니다. 위의 코드는 루프 본문을 전체 length
시간 동안 실행하며 누락 된 요소는 .. 과 같이 s
설정됩니다 . 대신에 희소 배열의 실제로 존재하는 요소 만 처리하려는 경우 인덱스에 간단한 테스트를 추가 할 수 있습니다 .undefined
for
of
.forEach
in
var i, s, myStringArray = [ "Hello", "World" ], len = myStringArray.length;
for (i=0; i<len; ++i) {
if (i in myStringArray) {
s = myStringArray[i];
// ... do something with s ...
}
}
myStringArray.length
루프 값에 전체 표현식 을 포함하는 것과 달리 로컬 변수에 길이 값을 지정하면 매번 특성 검색을 건너 뛰기 때문에 성능이 크게 달라질 수 있습니다. 내 컴퓨터에서 Rhino를 사용하면 속도가 43 % 향상됩니다.
다음과 같이 루프 초기화 절에서 수행 된 길이 캐싱을 볼 수 있습니다.
var i, len, myStringArray = [ "Hello", "World" ];
for (len = myStringArray.length, i=0; i<len; ++i) {
명시 적 카운팅 루프는 원하는 경우 각 값의 인덱스에 액세스 할 수 있음을 의미합니다. 인덱스는 전달한 함수에 추가 매개 변수로 전달 forEach
되므로 다음과 같이 액세스 할 수도 있습니다.
myStringArray.forEach( function(s, i) {
// ... do something with s and i ...
});
for
… of
각 객체와 관련된 색인을 제공하지는 않지만 반복하는 객체가 실제로 Array
( for
.. of
이 방법이 없을 수있는 다른 반복 가능한 유형에 작동하는 경우) Array를 사용할 수 있습니다 #entries 메소드를 사용하여 [index, item] 쌍의 배열로 변경 한 다음 반복합니다.
for (const [i, s] of myStringArray.entries()) {
// ... do something with s and i ...
}
for
… in
다른 사람에 의해 언급 구문은 객체의 속성에 걸쳐 반복입니다; JavaScript의 Array는 숫자 속성 이름 (및 자동으로 업데이트 된 length
속성)을 가진 객체이기 때문에 이론적으로 Array를 반복 할 수 있습니다. 그러나 문제는 그 자체가 숫자 속성 값으로 제한되지 않는다는 것입니다 (메소드조차도 실제로 값이 클로저 인 속성 일뿐입니다). 따라서 배열을 반복하는 데 for
… in
구문을 사용해서는 안됩니다 .
답변
당신은 사용할 수 있습니다 map
또한 같은 다른 언어로 가능한 기능적인 프로그래밍 기술이다, 파이썬 과 하스켈 .
[1,2,3,4].map( function(item) {
alert(item);
})
일반적인 구문은 다음과 같습니다.
array.map(func)
일반적으로 func
배열의 항목 인 하나의 매개 변수를 사용합니다. 그러나 JavaScript의 경우 항목의 인덱스 인 두 번째 매개 변수와 배열 자체 인 세 번째 매개 변수를 사용할 수 있습니다.
의 반환 값 array.map
은 다른 배열이므로 다음과 같이 사용할 수 있습니다.
var x = [1,2,3,4].map( function(item) {return item * 10;});
이제 x는 [10,20,30,40]
입니다.
함수를 인라인으로 작성할 필요는 없습니다. 별도의 기능 일 수 있습니다.
var item_processor = function(item) {
// Do something complicated to an item
}
new_list = my_list.map(item_processor);
이는 다음과 같습니다.
for (item in my_list) {item_processor(item);}
당신이를 제외하고는 new_list
.
답변
JavaScript에서는 for-in 루프를 사용하여 Array를 반복하는 것이 좋지 않지만 다음 for
과 같은 루프 를 사용하는 것이 좋습니다 .
for(var i=0, len=myArray.length; i < len; i++){}
또한 배열 길이를 “캐싱”합니다. 자세한 내용을 보려면 주제에 대한 내 게시물을 읽으십시오 .
답변
for (myStringArray의 문자) {
(직접 질문에 대답 : 지금 할 수 있습니다!)
대부분의 다른 답변은 옳지 만 ECMA Script 6 2015 가 반복, for..of
루프 를 수행하기위한 새로운 메커니즘을 도입하고 있다고 언급하지는 않습니다 .
이 새로운 구문은 자바 스크립트에서 배열을 반복하는 가장 우아한 방법입니다 (반복 색인이 필요하지 않은 한).
현재 Firefox 13 이상, Chrome 37 이상에서 작동하며 다른 브라우저에서는 기본적으로 작동하지 않습니다 (아래 브라우저 호환성 참조). 운 좋게도 오늘날 차세대 기능을 사용할 수 있는 JS 컴파일러 (예 : Babel )가 있습니다.
노드에서도 작동합니다 (버전 0.12.0에서 테스트했습니다).
배열 반복
// You could also use "let" instead of "var" for block scope.
for (var letter of ["a", "b", "c"]) {
console.log(letter);
}
객체 배열 반복
var band = [
{firstName : 'John', lastName: 'Lennon'},
{firstName : 'Paul', lastName: 'McCartney'}
];
for(var member of band){
console.log(member.firstName + ' ' + member.lastName);
}
생성기 반복 :
(예 : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for…of 에서 추출 )
function* fibonacci() { // a generator function
let [prev, curr] = [1, 1];
while (true) {
[prev, curr] = [curr, prev + curr];
yield curr;
}
}
for (let n of fibonacci()) {
console.log(n);
// truncate the sequence at 1000
if (n >= 1000) {
break;
}
}
호환성 테이블 :
http://kangax.github.io/es5-compat-table/es6/#For..of 루프
사양 : http://wiki.ecmascript.org/doku.php?id=harmony:iterators
}
답변
Opera, Safari, Firefox 및 Chrome은 이제 많은 공통 루프를 최적화하기 위해 일련의 향상된 배열 방법을 공유합니다.
모두 필요하지는 않지만 매우 유용하거나 모든 브라우저에서 지원하는 경우에 유용합니다.
Mozilla Labs는 자신과 WebKit이 모두 사용 하는 알고리즘을 공개하여 직접 추가 할 수 있습니다.
필터 는 일부 조건 또는 테스트를 만족하는 항목 배열을 반환합니다.
every 는 모든 배열 구성원이 테스트를 통과하면 true를 반환합니다.
일부 는 테스트를 통과하면 true를 반환합니다.
forEach 는 각 배열 멤버에서 함수를 실행하며 아무 것도 반환하지 않습니다.
map 은 forEach와 유사하지만 각 요소에 대한 연산 결과의 배열을 리턴합니다.
이러한 메소드는 모두 첫 번째 인수에 대한 함수를 취하고 선택적인 두 번째 인수를 갖습니다.이 인수는 함수를 반복 할 때 배열 멤버에 적용하려는 범위를 갖는 오브젝트입니다.
필요할 때까지 무시하십시오.
indexOf 및 lastIndexOf 는 해당 인수와 정확히 일치하는 첫 번째 또는 마지막 요소의 적절한 위치를 찾습니다.
(function(){
var p, ap= Array.prototype, p2={
filter: function(fun, scope){
var L= this.length, A= [], i= 0, val;
if(typeof fun== 'function'){
while(i< L){
if(i in this){
val= this[i];
if(fun.call(scope, val, i, this)){
A[A.length]= val;
}
}
++i;
}
}
return A;
},
every: function(fun, scope){
var L= this.length, i= 0;
if(typeof fun== 'function'){
while(i<L){
if(i in this && !fun.call(scope, this[i], i, this))
return false;
++i;
}
return true;
}
return null;
},
forEach: function(fun, scope){
var L= this.length, i= 0;
if(typeof fun== 'function'){
while(i< L){
if(i in this){
fun.call(scope, this[i], i, this);
}
++i;
}
}
return this;
},
indexOf: function(what, i){
i= i || 0;
var L= this.length;
while(i< L){
if(this[i]=== what)
return i;
++i;
}
return -1;
},
lastIndexOf: function(what, i){
var L= this.length;
i= i || L-1;
if(isNaN(i) || i>= L)
i= L-1;
else
if(i< 0) i += L;
while(i> -1){
if(this[i]=== what)
return i;
--i;
}
return -1;
},
map: function(fun, scope){
var L= this.length, A= Array(this.length), i= 0, val;
if(typeof fun== 'function'){
while(i< L){
if(i in this){
A[i]= fun.call(scope, this[i], i, this);
}
++i;
}
return A;
}
},
some: function(fun, scope){
var i= 0, L= this.length;
if(typeof fun== 'function'){
while(i<L){
if(i in this && fun.call(scope, this[i], i, this))
return true;
++i;
}
return false;
}
}
}
for(p in p2){
if(!ap[p])
ap[p]= p2[p];
}
return true;
})();
답변
소개
대학 시절부터 Java, JavaScript, Pascal, ABAP , PHP, Progress 4GL, C / C ++ 및 아마도 내가 생각할 수없는 다른 언어로 프로그래밍했습니다.
모두 고유 한 언어 특성이 있지만 이러한 각 언어는 동일한 기본 개념을 많이 공유합니다. 이러한 개념에는 프로 시저 / 함수,- IF
문,- FOR
루프 및- WHILE
루프가 포함됩니다.
전통적인 for
루프
전통적인 for
루프에는 세 가지 구성 요소가 있습니다.
- 초기화 : look 블록이 처음 실행되기 전에 실행
- 조건 : 루프 블록이 실행될 때마다 조건을 확인하고 false 인 경우 루프를 종료합니다.
- 추후 : 루프 블록이 실행될 때마다 수행
이 세 구성 요소는 ;
기호로 서로 분리되어 있습니다 . 이 세 가지 구성 요소 각각에 대한 내용은 선택 사항이므로 다음은 for
가능한 가장 작은 루프입니다.
for (;;) {
// Do stuff
}
물론, 당신은 포함해야합니다 if(condition === true) { break; }
또는 if(condition === true) { return; }
그 내부 어딘가 for
가 실행 중지 갈 수 -loop을.
그러나 일반적으로 초기화는 인덱스를 선언하는 데 사용되며 조건을 사용하여 해당 인덱스를 최소 또는 최대 값과 비교하고 이후에 인덱스를 증가시키는 데 사용됩니다.
for (var i = 0, length = 10; i < length; i++) {
console.log(i);
}
전통적인 for
루프를 사용 하여 어레이를 반복
배열을 반복하는 전통적인 방법은 다음과 같습니다.
for (var i = 0, length = myArray.length; i < length; i++) {
console.log(myArray[i]);
}
또는 뒤로 루프하는 것을 선호하는 경우 다음을 수행하십시오.
for (var i = myArray.length - 1; i > -1; i--) {
console.log(myArray[i]);
}
그러나 예를 들어 다음과 같은 많은 변형이 가능합니다.
for (var key = 0, value = myArray[key], length = myArray.length; key < length; value = myArray[++key]) {
console.log(value);
}
… 또는 이건 …
var i = 0, length = myArray.length;
for (; i < length;) {
console.log(myArray[i]);
i++;
}
… 또는 이것 :
var key = 0, value;
for (; value = myArray[key++];){
console.log(value);
}
가장 잘 작동하는 것은 주로 개인적인 취향과 구현중인 특정 사용 사례의 문제입니다.
이러한 각 변형은 매우 오래된 브라우저를 포함하여 모든 브라우저에서 지원됩니다!
while
루프
for
루프에 대한 한 가지 대안 은 while
루프입니다. 배열을 반복하려면 다음을 수행하십시오.
var key = 0;
while(value = myArray[key++]){
console.log(value);
}
기존 for
루프 와 마찬가지로 while
루프는 가장 오래된 브라우저에서도 지원됩니다.
또한 모든 while 루프를 루프로 다시 작성할 수 있습니다 for
. 예를 들어, 위의 while
루프는 다음과 같은 방식으로 작동합니다 for
.
for(var key = 0; value = myArray[key++];){
console.log(value);
}
For...in
과 for...of
JavaScript에서 다음을 수행 할 수도 있습니다.
for (i in myArray) {
console.log(myArray[i]);
}
그러나 for
모든 경우에 기존 루프 와 동일하게 작동하지 않으므로 고려해야 할 잠재적 부작용이 있으므로주의해서 사용해야합니다. 배열 반복과 함께 “for … in”을 사용하는 것이 좋지 않은 이유를 참조하십시오 .자세한 사항은.
에 대한 대안으로 for...in
현재도 있습니다 for...of
. 다음 예제는 for...of
루프와 루프 의 차이점을 보여줍니다 for...in
.
var myArray = [3, 5, 7];
myArray.foo = "hello";
for (var i in myArray) {
console.log(i); // logs 0, 1, 2, "foo"
}
for (var i of myArray) {
console.log(i); // logs 3, 5, 7
}
또한 Internet Explorer를 지원하지 않는 버전 for...of
( Edge 12+ 는 지원 하지 않음) 이상 이며 for...in
Internet Explorer 10 이상 이 필요하다는 점을 고려해야합니다 .
Array.prototype.forEach()
for
-loops 의 대안 Array.prototype.forEach()
은 다음 구문을 사용하는 것입니다.
myArray.forEach(function(value, key, myArray) {
console.log(value);
});
Array.prototype.forEach()
Internet Explorer 9 이상뿐만 아니라 모든 최신 브라우저에서 지원됩니다.
도서관
마지막으로 많은 유틸리티 라이브러리에도 고유 한 foreach
변형이 있습니다. 가장 인기있는 세 가지 AFAIK는 다음과 같습니다.
jQuery.each()
에서 jQuery를 :
$.each(myArray, function(key, value) {
console.log(value);
});
_.each(myArray, function(value, key, myArray) {
console.log(value);
});
_.forEach(myArray, function(value, key) {
console.log(value);
});