연관 배열 객체의 Javascript foreach 루프


182

for-each 루프가 JavaScript 연관 배열 객체를 반복하지 않는 이유는 무엇입니까?

// defining an array
var array = [];

// assigning values to corresponding keys
array["Main"] = "Main page";
array["Guide"] = "Guide page";
array["Articles"] = "Articles page";
array["Forum"] = "Forum board";

// expected: loop over every item,
// yet it logs only "last" assigned value - "Forum"
for (var i = 0; i < array.length; i++) {
    console.log(array[i]);
}

편집 : jQuery each()가 도움이 될 수 있습니다 : https://api.jquery.com/jQuery.each/


1
배열을 생성 한 다음이를 맵으로 사용합니다. 대신 일반 객체를 원하는 것 같습니다.
— Jon

4
associative arraysJS 와 같은 것은 없습니다 : 그것은 일반 배열이거나 객체입니다. 숫자가 아닌 속성을에 추가하는 것을 막을 수 Array는 없지만, 그렇게해서 associative특정 length속성이 자동으로 계산되지는 않습니다.
— raina77ow

3
re : JS에는 연관 배열과 같은 것이 없습니다. -다른 말로 표현하자면 : JavaScript는 "associative array"라는 이름 대신 "Object"라는 이름을 사용합니다. 그러나 ".length"속성이 없습니다.
— Jesse Chisholm

답변:


315

이 .length속성은 숫자 인덱스 (키)가 있는 속성 만 추적합니다. 키에 문자열을 사용하고 있습니다.

당신은 이것을 할 수 있습니다 :

var arr_jq_TabContents = {}; // no need for an array

arr_jq_TabContents["Main"] = jq_TabContents_Main;
arr_jq_TabContents["Guide"] = jq_TabContents_Guide;
arr_jq_TabContents["Articles"] = jq_TabContents_Articles;
arr_jq_TabContents["Forum"] = jq_TabContents_Forum;

for (var key in arr_jq_TabContents) {
    console.log(arr_jq_TabContents[key]);
}

안전을 위해 예기치 않은 상속 결과가없는 속성이 있는지 확인하는 것이 좋습니다.

for (var key in arr_jq_TabContents) {
  if (arr_jq_TabContents.hasOwnProperty(key))
    console.log(arr_jq_TabContents[key]);
}

편집 - Object.keys()현대 브라우저와 노드 등에서이 기능을 사용할 수 있습니다.이 기능은 객체의 "자체"키를 배열로 반환합니다.

Object.keys(arr_jq_TabContents).forEach(function(key, index) {
  console.log(this[key]);
}, arr_jq_TabContents);

에 전달 된 콜백 함수는에서 .forEach()반환 된 배열의 각 키와 키 색인으로 호출됩니다 Object.keys(). 또한 함수가 반복되는 배열을 전달했지만 해당 배열은 실제로 우리에게 유용하지 않습니다. 우리는 원래 객체 가 필요 합니다 . 이름으로 직접 액세스 할 수는 있지만 명시 적으로 전달하는 것이 조금 더 좋습니다. 콜백 내부에 .forEach()바인딩 될 원래 객체에 두 번째 인수를 전달하면 됩니다 this. (이것이 아래 주석에서 언급 된 것을 보았습니다.)


이게 var arr_jq_TabContents = {};뭐야? 내 말은 {}
— Szymon Toda

1
@Ultra 빈 객체 리터럴입니다. 변수가 새로운 빈 객체에 대한 참조로 초기화되었다는 것을 의미합니다.
— Pointy

@Ultra는 Array 인스턴스가 필요하지 않습니다. 그 코드에서는 JavaScript 배열처럼 사용하지 않기 때문입니다. JavaScript에는 다른 언어와 같이 "연관 배열"이 없습니다.
— Pointy

1
할당 []과 {}? 의 차이점은 무엇입니까 ? 다른 프로토 타입 만?
— SodeDead

8
hasOwnProperty를 사용하는 대신 모든 최신 웹 브라우저에서 다음을 사용하여 객체의 키를 반복 할 수 있어야합니다. Object.keys(arr_jq_TabContents).forEach( function(key) { ... } );
— Gregory Bell

80

이것은 매우 간단한 접근법입니다. 장점은 키도 얻을 수 있다는 것입니다.

for (var key in array) {
    var value = array[key];
    console.log(key, value);
}

ES6의 경우 :

array.forEach(value => {
  console.log(value)
})  

ES6의 경우 : (값, 색인 및 배열 자체를 원하는 경우)

array.forEach((value, index, self) => {
  console.log(value, index, self)
})  

12
var존재하지 않는 범위 지정을 제안하는 루프 에는 사용하지 마십시오 . var루프 앞이나 루프에서 사용하십시오 let.
— ceving

2
@ceving, 왜 루프에서 var를 사용하지 않는지 더 자세히 설명해 주시겠습니까? 나는 C ++ / PHP 배경에서 왔으며 이것을 이해하지 못한다. 범위 지정은 루프에 존재하지만 일시적이므로 귀하의 의미가 확실하지 않습니다.
— Dennis

6
@Dennis 대부분의 언어에서 for루프 의 변수 선언은 루프 본문으로 제한된 범위를 생성합니다 for. 그러나 JavaScript에서로 선언 된 변수는 루프 var에서 작성하더라도 항상 전역 함수 for입니다. 여기를 참조하십시오 : davidwalsh.name/for-and-against-let
— ceving

1
메모리 누출 자체가 아니라 "메모리 유출"입니다. varJavascript에서 루프가 완료된 후에도 메모리에 변수를 만듭니다.
— ahnbizcad

나는 "var"의 사용에 관한 이러한 의견의 요점은 일반적으로 "let"을 일반적으로 사용하지만 루프에서 사용하는 것이라고 생각합니다. 이유는 위에 설명되어 있지만 요약하면 "var"은 전역 범위를 만듭니다.
— DeeZone

6

이미 몇 가지 간단한 예가 있지만 PHP 배경에서 나온 것 같은 질문에 대해 어떻게 말했는지 알았으며 JavaScript가 동일한 방식으로 작동한다고 기대합니다. PHP array는 JavaScript와 매우 다릅니다 Array.

PHP에서 연관 배열은 숫자 인덱스 배열이 할 수있는 대부분의 array_*기능을 수행 할 수 있습니다 ( 함수 작동, count()배열 등) 단순히 배열을 만들고 숫자 대신 문자열 인덱스에 할당하기 시작합니다.

JavaScript에서 모든 것은 객체 (기본 요소를 제외하고 : 문자열, 숫자, 부울)이며 배열은 숫자 색인을 가질 수있는 특정 구현입니다. 배열에 푸시 아무것도 그 영향을 것 length, 그리고 (배열 방법을 사용하여 이상 반복 할 수있다 map, forEach, reduce, filter, find즉 당신이 무언가 때문에 모든 객체이기 때문에, 당신은 단순히 할당 특성에 무료로 항상있어, 그러나, 등) 모든 개체. 대괄호 표기법은 단순히 속성에 액세스하는 또 다른 방법이므로 귀하의 경우 :

array['Main'] = 'Main Page';

실제로 다음과 같습니다.

array.Main = 'Main Page';

귀하의 설명에서 필자는 '연관 배열'을 원하지만 JavaScript의 경우 객체를 해시 맵으로 사용하는 간단한 경우입니다. 또한 나는 그것이 예라는 것을 알고 있지만 변수 유형 만 설명하는 의미가없는 이름 (예 :) array과 포함해야 할 내용 (예 :)을 기반으로 한 이름은 피하십시오 pages. 간단한 객체는 너무 자주 우리는 먼저 사용하여 배열에 차례로 것, 반복 많은 좋은 직접적인 방법이 없습니다 Object(방법 Object.keys이 경우에 - 또한 거기 entries와 values지금 일부 브라우저에 추가)하는 우리는 루프 수 있습니다.

// assigning values to corresponding keys
const pages = {
  Main: 'Main page',
  Guide: 'Guide page',
  Articles: 'Articles page',
  Forum: 'Forum board',
};

Object.keys(pages).forEach((page) => console.log(page));

4

arr_jq_TabContents[key] 배열을 0 인덱스 형식으로 본다.


4

연관 배열을 일반 객체 유형으로 사용하는 간단한 방법은 다음과 같습니다.

Object.prototype.forEach = function(cb){
   if(this instanceof Array) return this.forEach(cb);
   let self = this;
   Object.getOwnPropertyNames(this).forEach(
      (k)=>{ cb.call(self, self[k], k); }
   );
};

Object({a:1,b:2,c:3}).forEach((value, key)=>{ 
    console.log(`key/value pair: ${key}/${value}`);
});



1

이것은 대부분의 경우 (본질적으로) 부정확합니다.

var array = [];
array["Main"] = "Main page";

그러면 배열에 이름이없는 비 요소 속성이 만들어집니다 Main. 배열은 객체이지만 일반적으로 요소가 아닌 속성을 만들고 싶지 않습니다.

array이러한 이름 으로 색인을 생성 하려면 일반적으로 Map배열이 아닌 일반 객체를 사용합니다 .

창의적이기 때문에 Map전화 할 (ES2015 +)를 사용하십시오 map.

let map = new Map();
map.set("Main", "Main page");

당신은 그것에서 반복자를 사용하여 반복 values, keys또는 entries예를 들어, 방법 :

for (const value of map.values()) {
    // Here, `value` will be `"Main page"`, etc.
}

창의적으로 부르는 일반 객체를 사용합니다 obj.

let obj = Object.create(null); // Creates an object with no prototype
obj.Main = "Main page"; // Or: `obj["Main"] = "Main page";`

당신은 그 사용 내용을 반복하는 것 Object.keys, Object.values또는 Object.entries예를 들어 :

for (const value of Object.values(proches_X)) {
    // Here, `value` will be `"Main page"`, etc.
}

0

var obj = {
  no: ["no", 32],
  nt: ["no", 32],
  nf: ["no", 32, 90]
};

count = -1; // which must be static value
for (i in obj) {
  count++;
  if (obj.hasOwnProperty(i)) {
    console.log(obj[i][count])
  };
};

이 코드에서는 array을 포함했기 때문에 배열의 호출 값에 대괄호 메서드를 사용했지만 변수 i에 속성 키가 있고 연결 배열의 두 값이라는 루프가있는 변수

당신이 관심이 있다면, 완벽한 방법


배열을 반복하지 않고 배열에 키가있는 객체를 반복합니다. 질문을 읽고 예제를보십시오.
— Pedro Joaquín

0

당신은 이것을 할 수 있습니다

var array = [];

// assigning values to corresponding keys
array[0] = "Main page";
array[1] = "Guide page";
array[2] = "Articles page";
array[3] = "Forum board";


array.forEach(value => {
    console.log(value)
})
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.