itsource

요소는 (…의 경우) 루프에서 정렬됩니다.

mycopycode 2022. 11. 26. 13:59
반응형

요소는 (…의 경우) 루프에서 정렬됩니다.

Javascript의 "for…in" 루프는 선언된 순서대로 해시 테이블/요소를 루프합니까?순서대로 안 되는 브라우저가 있나요?
사용하고 싶은 오브젝트는 한 번 선언되어 수정되지 않습니다.

예를 들어 다음과 같습니다.

var myObject = { A: "Hello", B: "World" };

또, 이하에 사용합니다.

for (var item in myObject) alert(item + " : " + myObject[item]);

대부분의 괜찮은 브라우저에서 'A: "Hello"가 항상 'B: "World"보다 먼저 나오기를 기대할 수 있을까요?

John Resig 인용:

현재 모든 주요 브라우저는 정의된 순서대로 개체의 속성을 루프합니다.몇 가지 경우를 제외하고 Chrome도 이 작업을 수행합니다. [...] 이 동작은 ECMAScript 사양에 의해 명시적으로 정의되지 않은 상태로 유지됩니다.ECMA-262의 섹션 12.6.4:

성질을 열거하는 방법...구현에 의존합니다.

그러나 사양은 구현과 상당히 다릅니다.ECMAScript의 모든 최신 구현은 정의된 순서대로 개체 속성을 반복합니다.이로 인해 Chrome 팀은 이것을 버그로 간주하여 수정하게 되었습니다.

모든 브라우저는 모든 비숫자 속성 이름에 적용되는 Chrome 및 Opera를 제외하고 정의 순서를 준수합니다.이들 2개의 브라우저에서는 속성이 첫 번째 비숫자 속성 앞에 순서대로 표시됩니다(이는 어레이 구현 방법과 관련이 있습니다).순서는 동일합니다.Object.keys뿐만 아니라.

이 예에서는, 무슨 일이 일어나는지를 명확하게 할 필요가 있습니다.

var obj = {
  "first":"first",
  "2":"2",
  "34":"34",
  "1":"1",
  "second":"second"
};
for (var i in obj) { console.log(i); };
// Order listed:
// "1"
// "2"
// "34"
// "first"
// "second"

이 문제의 기술적 문제는 언제든지 변경될 수 있다는 사실보다 덜 중요합니다.이런 식으로 있는 것에 의존하지 마세요.

요컨대 순서가 중요한 경우에는 어레이를 사용합니다.

1년 후에 이걸 부딪히다니...

2012년이 되었지만 주요 브라우저는 여전히 다릅니다.

function lineate(obj){
    var arr = [], i;
    for (i in obj) arr.push([i,obj[i]].join(':'));
    console.log(arr);
}
var obj = { a:1, b:2, c:3, "123":'xyz' };
/* log1 */  lineate(obj);
obj.a = 4;
/* log2 */  lineate(obj);
delete obj.a;
obj.a = 4;
/* log3 */  lineate(obj);

현재 브라우저의 gist 또는 테스트

Safari 5, Firefox 14

["a:1", "b:2", "c:3", "123:xyz"]
["a:4", "b:2", "c:3", "123:xyz"]
["b:2", "c:3", "123:xyz", "a:4"]

Chrome 21, Opera 12, Node 0.6, Firefox 27

["123:xyz", "a:1", "b:2", "c:3"]
["123:xyz", "a:4", "b:2", "c:3"]
["123:xyz", "b:2", "c:3", "a:4"]

IE9

[123:xyz,a:1,b:2,c:3] 
[123:xyz,a:4,b:2,c:3] 
[123:xyz,a:4,b:2,c:3] 

ECMAScript Language Specification(ECMAScript 언어사양), 섹션 12.6.4(의for .. in루프):

속성을 열거하는 메커니즘은 구현에 따라 다릅니다.열거 순서는 개체에 의해 정의됩니다.

섹션 4.3.3 ('개체'의 정의):

각 속성에는 원시 값, 개체 또는 함수가 포함되어 있는 무질서한 속성 집합입니다.객체의 속성에 저장된 함수를 메서드라고 합니다.

이는 JavaScript 구현 간에 일관된 순서로 열거되는 속성을 신뢰할 수 없다는 것을 의미합니다.(어쨌든 언어의 구현 고유의 세부 사항에 의존하는 것은 좋지 않은 스타일입니다.)

순서를 정의하려면 순서를 정의하는 것을 실장해야 합니다.예를 들어 오브젝트에 액세스하기 전에 정렬하는 키의 배열 등입니다.

열거하는 객체의 요소는 DontEnum 플래그가 설정되어 있지 않은 속성입니다.ECMAScript(Javascript)는 "개체는 속성들의 순서없는 집합"이라고 명시되어 있습니다(http://www.mozilla.org/js/language/E262-3.pdf 섹션 8.6 참조).

모든 Javascript 구현이 선언 순서대로 열거된다고 가정하는 것은 표준에 부합하지 않습니다(즉, 안전합니다).

반복 순서는 속성 삭제에 관해서도 혼동되지만, 이 경우 IE에만 해당됩니다.

var obj = {};
obj.a = 'a';
obj.b = 'b';
obj.c = 'c';

// IE allows the value to be deleted...
delete obj.b;

// ...but remembers the old position if it is added back later
obj.b = 'bb';
for (var p in obj) {
    alert(obj[p]); // in IE, will be a, bb, then c;
                   // not a, c, then bb as for FF/Chrome/Opera/Safari
}

반복 순서를 수정하기 위해 스펙을 변경하려는 욕구는 개발자들 사이에서 꽤 인기 있는 것으로 보인다. 만약 http://code.google.com/p/v8/issues/detail?id=164에서의 토론이 어떤 징후가 있다면 말이다.

IE6에서는 순서가 보증되지 않습니다.

주문을 신뢰할 수 없습니다.Opera와 Chrome 모두 정렬되지 않은 속성 목록을 반환합니다.

<script type="text/javascript">
var username = {"14719":"A","648":"B","15185":"C"};

for (var i in username) {
  window.alert(i + ' => ' + username[i]);
}
</script>

위의 코드는 오페라에서는 B, A, C, 크롬에서는 C, A, B를 나타내고 있습니다.

다른 답변에서도 알 수 있듯이, 아니요, 순서는 보장되지 않습니다.

순서를 반복하는 경우는, 다음과 같은 조작을 실행할 수 있습니다.

let keys = Object.keys(myObject);
for (let key of keys.sort()) {
  let value = myObject[key];
  
  // Do what you want with key and value 
}

성능 면에서는 최적은 아니지만 알파벳 순으로 멋진 표시를 원하는 경우 가격이 적당하다는 점에 유의하십시오.

이는 질문 자체에 대한 해답은 아니지만 기본적인 문제에 대한 해결책을 제공합니다.

보존 순서에 의존할 수 없는 경우 키와 값을 가진 객체 배열을 속성으로 사용하면 어떨까요?

var myArray = [
    {
        'key'   : 'key1'
        'value' : 0
    },
    {
        'key'   : 'key2',
        'value' : 1
    } // ...
];

여기서 키가 고유한지 확인하는 것은 사용자에게 달려 있습니다(이것도 중요하다고 가정).for (...in...)이제 인덱스를 '키'로 반환합니다.

> console.log(myArray[0].key);
key1

> for (let index in myArray) {console.log(myArray[index].value);}
0
1
See the Pen (...에) 순서대로 주소를 지정하기 위해서. by JDQ ( @JDQ) on 코드펜.

2022년 현재,

Chrome이 정의 순서를 따르지 않는다는 것을 방금 알았습니다.그것은 오히려 알파벳 순으로 정렬하지만 자연스럽지는 않다.예를 들어 키 "a12"는 "a3" 앞에 나옵니다.그러니 조심하세요.

언급URL : https://stackoverflow.com/questions/280713/elements-order-in-a-for-in-loop

반응형