연관 배열 객체의 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이 경우에 - 또한 거기 entriesvalues지금 일부 브라우저에 추가)하는 우리는 루프 수 있습니다.

// 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.