자바 스크립트에서 배열이 잘못된 'for (var item in list)'인 이유는 무엇입니까?


78

0 기반의 숫자 인덱스 배열이 주어지면 :

var list = ['Foo', 'Bar', 'Baz'];

여러 번, 누군가가 다음과 같은 배열의 변수를 통해 루프를 제안 할 때 발견했습니다.

for(var item in list) { ... }

... 거의 확실히 누군가가 그것이 나쁜 관행이라고 제안하고 다른 접근 방식을 제안합니다.

var count = list.length;

for(var i = 0; i < count; i++) {
    var item = list[i];
    ...
}

위의 더 간단한 버전을 사용하지 않고 대신 두 번째 예제를 사용하는 이유는 무엇입니까?


해당 루프로 항목을 반복하지 않고 키 / 속성 이름 / indizes를 반복합니다.
Bergi

5
또한 빅토리아 시대의 C 코더는 iiterators를 이해하지 못합니다. 그러나 값이 아닌 키를 뱉어내는 것을 명심하십시오. for (;;) 형식은 더 빠르지 만 99 %의 경우 실제로 중요하지 않습니다. 메가 프로젝트 또는 최적화가 필요한 작업을 수행하지 않는 한 코더 시간은 계산 시간보다 비쌉니다.
Shayne

답변:


96

첫째, 루프의 순서가 루프에 대해 정의되어 있지 for...in않으므로 속성이 원하는 순서로 반복된다는 보장이 없습니다.

둘째, for...in프로토 타입에서 상속 된 속성을 포함하여 개체의 모든 열거 가능한 속성을 반복합니다. 배열의 경우, 페이지에 포함 된 코드 나 라이브러리가의 프로토 타입을 보강 한 경우 영향을 미칠 Array수 있습니다. 이는 진정으로 유용한 작업이 될 수 있습니다.

Array.prototype.remove = function(val) {
    // Irrelevant implementation details
};

var a = ["a", "b", "c"];

for (var i in a) {
    console.log(i);
}

// Logs 0, 1, 2, "remove" (though not necessarily in that order)

2
hasOwnProperty그래도 사용하는 한 괜찮습니다 for (var i in a) { if (a.hasOwnProperty(i)) console.log(i); }--> 1 2 3
Dimitar Christoff

11
한 가지 제안,로 변경 over all properties하십시오 over **enumerable** properties. 최신 자바 스크립트 구현에서는 속성을로 enumerable설정 하여 속성을 정의 할 수 있습니다 false. 기본 제공 자바 스크립트 개체의 이러한 속성 및 속성은 for...in.
Andy E

4
@Dimitar : 사실, 일단 그것을 추가하면 루프는 표준 C 스타일 for 루프보다 더 단순 해 보이지 않습니다.
Tim Down

1
어쨌든-배열을 반복하는 유일한 합법적 인 이유는 배열 키를 얻는 것입니다 (javscript의 배열 특성으로 인해 작동 함)-다른 이유가 있으면 일반 루프를 수행하는 것이 좋습니다.
Dimitar Christoff


1

이와 같이 for / in을 사용하면 item문자열 값 "0", "1", ...을 통해 열거되므로 목록의 실제 개체가 아닙니다. 따라서 첫 번째 스 니펫의 '항목' iitem. 또한 문자열 값은 숫자가 예상되는 곳에 열거됩니다. 그리고 목록에 속성을 지정할 때 문제가 발생합니다 array.ID = "a123".

그러나 이러한 단점으로 인해 팀이 수행하는 작업을 알고 있다면 구문이 여전히 매우 유용하다고 생각합니다.


1

for ... in ... 목록 항목을 반환하지 않고 대신 배열 속성을 열거합니다.

그 이유만으로는 루프를 대체 할 수 없습니다for (i=0; i<arr.length; i++) .

적절한 대안은 for ... of ...구성입니다. 배열과 같은 반복 가능한 개체의 값을 열거합니다. MDN 웹 문서 ( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of) 에서 자세한 내용을 읽을 수 있습니다.

관련 최신 브라우저에서 지원됩니다 (Internet Explorer는 포함되지 않으며 Microsoft Edge로 대체 됨). 구형 브라우저를 지원하지 않을 여유가 있다면 아마도 갈 길일 것입니다. 미리 링크 된 MDN 페이지 끝에있는 편리한 브라우저 지원 표를 확인하여 실제로 for ... of ...사용 이 허용되는 브라우저 버전을 확인할 수 있습니다.


IE에 대한 귀하의 주장이 사실이고 신뢰할 수 있다는 사실을 알게되어 기쁩니다. :)
CapelliC

0

추가 list.foo = bar;하고 간단한 for. 일부 라이브러리 (예 : prototypeJs)를 사용하지 않고 배열 객체에 새 속성을 추가하지 않으면 간단한 for 문을 사용할 수 있습니다.

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