[javascript] “for (… in…)”루프의 요소 순서
Javascript의 “for… in”루프는 해시 테이블 / 요소를 선언 된 순서대로 반복합니까? 순서대로하지 않는 브라우저가 있습니까?
사용하려는 객체가 한 번 선언 되고 수정되지 않습니다.
내가 가지고 있다고 가정 해보십시오.
var myObject = { A: "Hello", B: "World" };
그리고 나는 그들을 더 사용합니다 :
for (var item in myObject) alert(item + " : " + myObject[item]);
가장 괜찮은 브라우저에서 ‘A : “Hello”가 항상’B : “World” ‘앞에 올 것으로 기대할 수 있습니까?
답변
인용 존 레식 :
현재 모든 주요 브라우저는 객체의 속성을 정의 된 순서대로 반복합니다. Chrome은 몇 가지 경우를 제외하고이 작업도 수행합니다. […]이 동작은 ECMAScript 사양에 의해 명시 적으로 정의되어 있지 않습니다. ECMA-262의 섹션 12.6.4 :
속성을 열거하는 메커니즘은 구현에 따라 다릅니다.
그러나 사양은 구현과는 다릅니다. ECMAScript의 모든 최신 구현은 정의 된 순서대로 객체 속성을 반복합니다. 이 때문에 Chrome 팀은이 버그로 간주하여 수정합니다.
모든 비 숫자 속성 이름에 대해 수행하는 Chrome 및 Opera를 제외한 모든 브라우저는 정의 순서 를 따릅니다. 이 두 브라우저에서 속성은 숫자가 아닌 첫 번째 속성보다 순서대로 가져옵니다 (배열을 구현하는 방법과 관련이 있음). 순서도 동일 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);
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, 노드 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 언어 사양 (온 섹션 12.6.4 for .. in
루프) :
속성을 열거하는 메커니즘은 구현에 따라 다릅니다. 열거 순서는 개체에 의해 정의됩니다.
4.3.3 절 ( “객체”의 정의) :
순서가없는 속성 모음으로 각각 기본 값, 객체 또는 함수를 포함합니다. 객체의 속성에 저장된 함수를 메서드라고합니다.
JavaScript 구현에서 일관된 순서로 열거되는 속성에 의존 할 수 없다는 것을 의미합니다. (어쨌든 언어의 구현 별 세부 사항에 의존하는 것은 나쁜 스타일입니다.)
주문을 정의하려면 객체에 액세스하기 전에 정렬하는 키 배열과 같이 주문을 정의하는 것을 구현해야합니다.
답변
for / in 열거하는 객체의 요소는 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>
위의 코드는 Opera의 B, A, C 및 Chrome의 C, A, B를 보여줍니다.