etc./StackOverFlow

배열 반복에 "for...in"을 사용하는 것이 나쁜 생각인 이유는 무엇입니까?

청렴결백한 만능 재주꾼 2021. 12. 20. 10:11
반응형

질문자 :lYriCAlsSH


JavaScript에서 배열과 함께 for...in 을 사용하지 말라고 들었습니다. 왜 안 돼?



그 이유는 하나의 구성이 다음과 같기 때문입니다.

 var a = []; // Create a new empty array. a[5] = 5; // Perfectly legal JavaScript that resizes the array. for (var i = 0; i < a.length; i++) { // Iterate over numeric indexes from 0 to 5, as everyone expects. console.log(a[i]); } /* Will display: undefined undefined undefined undefined undefined 5 */

때로는 완전히 다를 수 있습니다.

 var a = []; a[5] = 5; for (var x in a) { // Shows only the explicitly set index of "5", and ignores 0-4 console.log(x); } /* Will display: 5 */

또한 JavaScript 라이브러리가 다음과 같은 작업을 수행할 수 있다는 점을 고려하십시오. 이는 생성하는 모든 배열에 영향을 미칩니다.

 // Somewhere deep in your JavaScript library... Array.prototype.foo = 1; // Now you have no idea what the below code will do. var a = [1, 2, 3, 4, 5]; for (var x in a){ // Now foo is a part of EVERY array and // will show up here as a value of 'x'. console.log(x); } /* Will display: 0 1 2 3 4 foo */


Triptych

for-in 문 자체는 "나쁜 습관"이 아니지만 예를 들어 배열이나 배열과 유사한 객체 를 반복 하는 데 오용될 수 있습니다.

for-in 문의 목적은 객체 속성을 열거 하는 것입니다. 이 명령문은 프로토타입 체인에 올라가 상속된 속성을 열거하기도 합니다. 때로는 원하지 않는 경우도 있습니다.

또한 반복 순서는 사양에 의해 보장되지 않습니다. 즉, 배열 개체를 "반복"하려는 경우 이 명령문을 사용하면 속성(배열 인덱스)이 숫자 순서로 방문되는지 확신할 수 없습니다.

예를 들어, JScript(IE <= 8)에서 Array 객체에서도 열거 순서는 속성이 생성될 때 정의됩니다.

 var array = []; array[2] = 'c'; array[1] = 'b'; array[0] = 'a'; for (var p in array) { //... p will be "2", "1" and "0" on IE }

또한 상속된 속성에 대해 말하면 예를 들어 MooTools와 같은 일부 라이브러리와 같이 Array.prototype

 Array.prototype.last = function () { return this[this.length-1]; }; for (var p in []) { // an empty array // last will be enumerated }

이전에 배열이나 배열과 유사한 객체 를 반복 하기 위해 말했듯 for / while 루프와 같은 순차 루프를 사용하는 것입니다.

객체의 고유한 속성 (상속되지 않은 속성)만 열거하려는 hasOwnProperty 메서드를 사용할 수 있습니다.

 for (var prop in obj) { if (obj.hasOwnProperty(prop)) { // prop is not inherited } }

Object.prototype hasOwnProperty 라는 속성을 추가하는 경우 문제가 발생하지 않도록 Object.prototype에서 직접 메서드를 호출하는 것이 좋습니다.

 for (var prop in obj) { if (Object.prototype.hasOwnProperty.call(obj, prop)) { // prop is not inherited } }

Christian C. Salvadó

배열 요소를 반복 for..in 을 사용하지 말아야 하는 세 가지 이유가 있습니다.

  • for..in 은 DontEnum이 아닌 배열 객체의 모든 고유 및 상속 속성을 DontEnum . 즉, 누군가가 특정 배열 객체에 속성을 추가하거나(이에 대한 타당한 이유가 있습니다. 제가 직접 수행했습니다) Array.prototype 변경한 경우(다른 스크립트와 잘 작동해야 하는 코드에서 나쁜 습관으로 간주됨) 이러한 속성도 반복됩니다. hasOwnProperty() 를 확인하여 제외할 수 있지만 배열 개체 자체에 설정된 속성에는 도움이 되지 않습니다.

  • for..in 은 요소 순서 유지를 보장하지 않습니다.

  • 배열 개체와 전체 프로토타입 체인의 모든 속성을 살펴보고 여전히 속성의 이름만 가져오기 때문에 속도가 느립니다. 즉, 값을 가져오려면 추가 조회가 필요합니다.


Christoph

for...in은 배열 자체가 아니라 배열을 보유하는 객체를 열거하기 때문입니다. 배열 프로토타입 체인에 함수를 추가하면 해당 기능도 포함됩니다. 즉

 Array.prototype.myOwnFunction = function() { alert(this); } a = new Array(); a[0] = 'foo'; a[1] = 'bar'; for(x in a){ document.write(x + ' = ' + a[x]); }

이것은 다음과 같이 쓸 것입니다:

0 = 푸
1 = 바
myOwnFunction = function() { 경고(이); }

그리고 프로토타입 체인에 아무것도 추가되지 않을 것이라고 확신할 수 없기 때문에 for 루프를 사용하여 배열을 열거하면 됩니다.

 for(i=0,x=a.length;i<x;i++){ document.write(i + ' = ' + a[i]); }

이것은 다음과 같이 쓸 것입니다:

0 = 푸
1 = 바

Pim Jager

2016년(ES6) 현재 John Slegers가 이미 알아차린 것처럼 배열 반복 for…of

이 간단한 데모 코드를 추가하여 더 명확하게 하고 싶습니다.

 Array.prototype.foo = 1; var arr = []; arr[5] = "xyz"; console.log("for...of:"); var count = 0; for (var item of arr) { console.log(count + ":", item); count++; } console.log("for...in:"); count = 0; for (var item in arr) { console.log(count + ":", item); count++; }

콘솔에는 다음이 표시됩니다.

 for...of: 0: undefined 1: undefined 2: undefined 3: undefined 4: undefined 5: xyz for...in: 0: 5 1: foo

다시 말해:

  • for...of 는 0에서 5까지 계산하고 Array.prototype.foo 도 무시합니다. 그것은 배열 값을 보여줍니다.

  • for...in 5 만 나열하고 정의되지 않은 배열 인덱스를 무시하고 foo 추가합니다. 배열 속성 이름을 보여줍니다.


MarcG

따로따로 배열에서 for-in을 사용하는 것은 아무런 문제가 없습니다. For-in은 객체의 속성 이름을 반복하며 "즉시 사용 가능한" 배열의 경우 속성이 배열 인덱스에 해당합니다. length , toString 등과 같은 내장 속성은 반복에 포함되지 않습니다.)

그러나 코드(또는 사용 중인 프레임워크)가 사용자 정의 속성을 배열이나 배열 프로토타입에 추가하면 이러한 속성이 반복에 포함되며 이는 아마도 원하는 것이 아닐 것입니다.

Prototype과 같은 일부 JS 프레임워크는 Array 프로토타입을 수정합니다. JQuery와 같은 다른 프레임워크는 그렇지 않으므로 JQuery를 사용하면 for-in을 안전하게 사용할 수 있습니다.

확실하지 않은 경우 for-in을 사용하면 안 됩니다.

배열을 반복하는 다른 방법은 for 루프를 사용하는 것입니다.

 for (var ix=0;ix<arr.length;ix++) alert(ix);

그러나 이것은 다른 문제가 있습니다. 문제는 JavaScript 배열에 "구멍"이 있을 수 있다는 것입니다. arr 을 다음과 같이 정의하는 경우:

 var arr = ["hello"]; arr[100] = "goodbye";

그런 다음 배열에는 두 개의 항목이 있지만 길이는 101입니다. for-in을 사용하면 두 개의 인덱스가 생성되는 반면 for-loop는 101개의 인덱스를 생성합니다. 여기서 99는 undefined 값을 갖습니다.


JacquesB

짧은 대답: 가치가 없습니다.


더 긴 대답: 순차 요소 순서와 최적의 성능이 필요하지 않더라도 가치가 없습니다.


긴 답변: 가치가 없습니다...

  • for (var property in array) 를 사용하면 array 이 객체 로 반복되어 객체 프로토타입 체인을 통과하고 궁극적으로 인덱스 기반 for 루프보다 느리게 수행됩니다.
  • for (... in ...) 는 예상대로 개체 속성을 순차적으로 반환하지 않습니다.
  • hasOwnProperty()!isNaN() 검사를 사용하면 추가 오버헤드가 발생하여 수행 속도가 훨씬 느려지고 처음에 사용하는 주요 이유가 무효화됩니다. 즉, 형식이 더 간결하기 때문입니다.

이러한 이유로 성능과 편의성 사이에 허용 가능한 절충안이 존재하지 않습니다. 배열을 개체 로 처리하고 배열의 개체 속성에 대한 작업을 수행하는 것이 목적이 아니면 실제로 아무런 이점이 없습니다.


WynandB

다른 답변에 제공된 이유 외에도 루프가 개체 속성의 이름을 반복하므로 변수가 있으므로 카운터 변수로 수학을 수행해야 하는 경우 "for...in" 구조를 사용하고 싶지 않을 수 있습니다. 문자열입니다.

예를 들어,

 for (var i=0; i<a.length; i++) { document.write(i + ', ' + typeof i + ', ' + i+1); }

쓸 것이다

 0, number, 1 1, number, 2 ...

반면,

 for (var ii in a) { document.write(i + ', ' + typeof i + ', ' + i+1); }

쓸 것이다

 0, string, 01 1, string, 11 ...

물론 이것은 다음을 포함하여 쉽게 극복할 수 있습니다.

 ii = parseInt(ii);

루프에 있지만 첫 번째 구조가 더 직접적입니다.


ctmiddle

for ... in 루프가 모든 열거 가능한 속성("모든 배열 요소"와 동일 하지 않음 !)에 대한 사실을 제외하고 http://www.ecma-international.org/publications/files/ECMA-ST를 참조하십시오. /Ecma-262.pdf , 섹션 12.6.4(5판) 또는 13.7.5.15(7판):

속성을 열거하는 역학과 순서 가 지정되지 않았습니다 ...

(나를 강조한다.)

즉, 브라우저가 원하는 경우 삽입된 순서대로 속성을 통과할 수 있습니다. 또는 번호순으로. 또는 사전순으로(여기서 "30"은 "4"보다 먼저 옵니다! 모든 객체 키, 따라서 모든 배열 인덱스)는 실제로 문자열이므로 완전히 의미가 있습니다. 객체를 해시 테이블로 구현한 경우 버킷별로 통과할 수 있습니다. 또는 그 중 하나를 가져 와서 "뒤로"를 추가하십시오. 브라우저는 각 속성을 정확히 한 번만 방문하기만 하면 무작위로 반복되고 ECMA-262를 준수할 수도 있습니다.

실제로 대부분의 브라우저는 현재 거의 동일한 순서로 반복하는 것을 선호합니다. 그러나 그들이 해야 한다는 말은 없습니다. 이는 구현에 따라 다르며 훨씬 더 효율적인 다른 방법이 발견되면 언제든지 변경할 수 있습니다.

어느 쪽이든, for ... in 은 순서를 의미하지 않습니다. 순서가 중요하다면 이에 대해 명시하고 인덱스가 for


cHao

주로 두 가지 이유:

하나

다른 사람들이 말했듯이 배열에 없거나 프로토타입에서 상속된 키를 얻을 수 있습니다. 따라서 라이브러리가 Array 또는 Object 프로토타입에 속성을 추가한다고 가정해 보겠습니다.

 Array.prototype.someProperty = true

모든 배열의 일부로 얻을 수 있습니다.

 for(var item in [1,2,3]){ console.log(item) // will log 1,2,3 but also "someProperty" }

hasOwnProperty 메소드를 사용하여 이 문제를 해결할 수 있습니다.

 var ary = [1,2,3]; for(var item in ary){ if(ary.hasOwnProperty(item)){ console.log(item) // will log only 1,2,3 } }

그러나 이것은 for-in 루프가 있는 모든 객체를 반복하는 경우에 해당됩니다.

일반적으로 배열에 있는 항목의 순서는 중요하지만 for-in 루프가 반드시 올바른 순서로 반복되는 것은 아닙니다. 이는 배열을 JS에서 구현되는 방식인 객체로 취급하기 때문입니다. 배열로. 이것은 작은 일처럼 보이지만 실제로 응용 프로그램을 망칠 수 있고 디버그하기 어렵습니다.


Lior

인덱스가 아닌 개체 필드를 통해 열거하기 때문입니다. 인덱스 "길이"로 가치를 얻을 수 있으며 이것을 원하는지 의심됩니다.


vava

예를 들어 추가할 내용이 별로 없는 것 같습니다. 경우에 따라 for...in 사용하는 이유에 대한 Triptych의 답변 또는 CMS의 답변을 피해야 합니다.

그러나 나는 최신 브라우저에 대한 대안이 있음을 추가하고 싶습니다 않습니다 for...in 그 이러한 경우에 사용할 수 있습니다 for...in 사용할 수 없습니다. 그 대안은 for...of :

 for (var item of items) { console.log(item); }

메모 :

불행히도 Internet Explorer 버전은 for...of ( Edge 12+ 는 지원)를 지원하지 않으므로 클라이언트 측 프로덕션 코드에서 사용할 수 있을 때까지 조금 더 기다려야 합니다. 그러나 서버 측 JS 코드에서 사용하는 것이 안전해야 합니다( Node.js 를 사용하는 경우).


John Slegers

for ... in ... 의 문제 — 이것은 프로그래머가 실제로 언어를 이해하지 못할 때만 문제가 됩니다. 그것은 실제로 버그나 그 밖의 것이 아닙니다. 객체의 모든 구성원을 반복한다는 것입니다(모든 열거 가능한 구성원이지만 지금은 세부 사항입니다). 배열의 인덱싱된 속성만 반복하려는 경우 의미상 일관성을 유지하는 유일한 방법은 정수 인덱스(즉, for (var i = 0; i < array.length; ++i) 스타일 루프).

모든 개체는 연결된 임의의 속성을 가질 수 있습니다. 특히 배열 인스턴스에 추가 속성을 로드하는 것은 끔찍한 일이 아닙니다. 따라서 인덱싱된 배열과 유사한 속성 보려는 코드는 정수 인덱스를 고수 해야 합니다. for ... in 이 하는 일을 완전히 인식하는 코드는 모든 속성을 볼 필요 가 있으며, 그것도 괜찮습니다.


Pointy

TL&DR: for in 루프를 사용하는 것은 나쁘지 않습니다. 사실 그 반대입니다.

for in 루프는 배열에서 올바르게 사용된다면 JS의 보석이라고 생각합니다. 당신은 당신의 소프트웨어를 완전히 통제하고 당신이 하고 있는 일을 알고 있어야 합니다. 언급된 단점들을 하나씩 살펴보고 반증해보자.

  1. 상속된 속성도 반복합니다. Array.prototype 에 대한 모든 확장 Object.defineProperty() 를 사용하여 수행되어야 하고 enumerable false 로 설정되어야 합니다. 그렇게 하지 않는 라이브러리는 전혀 사용해서는 안됩니다.
  2. 상속 체인에 추가하는 속성은 나중에 계산됩니다. Object.setPrototypeOf 또는 Class extend 의한 배열 하위 분류를 수행할 때. 기본적으로 writable , enumerableconfigurable 가능한 속성 설명자를 false Object.defineProperty() 를 다시 사용해야 합니다. 여기에서 배열 하위 분류 예제를 살펴보겠습니다...

 function Stack(...a){ var stack = new Array(...a); Object.setPrototypeOf(stack, Stack.prototype); return stack; } Stack.prototype = Object.create(Array.prototype); // now stack has full access to array methods. Object.defineProperty(Stack.prototype,"constructor",{value:Stack}); // now Stack is a proper constructor Object.defineProperty(Stack.prototype,"peak",{value: function(){ // add Stack "only" methods to the Stack.prototype. return this[this.length-1]; } }); var s = new Stack(1,2,3,4,1); console.log(s.peak()); s[s.length] = 7; console.log("length:",s.length); s.push(42); console.log(JSON.stringify(s)); console.log("length:",s.length); for(var i in s) console.log(s[i]);

따라서 .. for in 루프는 이제 코드에 관심을 두었기 때문에 안전합니다.

  1. for in 루프가 느립니다 . 때때로 필요한 희소 배열을 반복하는 경우 가장 빠른 반복 방법입니다. 이것은 알아야 할 가장 중요한 성능 트릭 중 하나입니다. 예를 들어 보겠습니다. 희소 배열을 반복합니다.

 var a = []; a[0] = "zero"; a[10000000] = "ten million"; console.time("for loop on array a:"); for(var i=0; i < a.length; i++) a[i] && console.log(a[i]); console.timeEnd("for loop on array a:"); console.time("for in loop on array a:"); for(var i in a) a[i] && console.log(a[i]); console.timeEnd("for in loop on array a:");


Redu

또한 의미론으로 인해 배열(즉, 다른 JavaScript 객체와 동일)을 처리 for, in

 // C# char[] a = new char[] {'A', 'B', 'C'}; foreach (char x in a) System.Console.Write(x); //Output: "ABC" // Java char[] a = {'A', 'B', 'C'}; for (char x : a) System.out.print(x); //Output: "ABC" // PHP $a = array('A', 'B', 'C'); foreach ($a as $x) echo $x; //Output: "ABC" // JavaScript var a = ['A', 'B', 'C']; for (var x in a) document.write(x); //Output: "012"

matpop

인덱스가 정수가 아니라 문자열이기 때문에 다른 문제 외에도 "for..in" 구문이 더 느릴 수 있습니다.

 var a = ["a"] for (var i in a) alert(typeof i) // 'string' for (var i = 0; i < a.length; i++) alert(typeof i) // 'number'

dc1

중요한 측면은 for...in 은 열거 가능한 속성 속성 이 true로 설정된 개체에 포함된 속성에 대해서만 반복한다는 것입니다. for...in 을 사용하여 객체를 반복하려고 시도하면 열거 가능한 속성 속성이 false인 경우 임의의 속성이 누락될 수 있습니다. 특정 요소가 열거되지 않도록 일반 Array 객체에 대한 열거 가능한 속성 속성을 변경하는 것이 가능합니다. 일반적으로 속성 속성은 객체 내의 함수 속성에 적용되는 경향이 있습니다.

다음을 통해 속성의 열거 가능한 속성 속성 값을 확인할 수 있습니다.

 myobject.propertyIsEnumerable('myproperty')

또는 네 가지 속성 속성을 모두 얻으려면:

 Object.getOwnPropertyDescriptor(myobject,'myproperty')

이것은 ECMAScript 5에서 사용할 수 있는 기능입니다. 이전 버전에서는 열거 가능한 속성 속성의 값을 변경할 수 없었습니다(항상 true로 설정됨).


Pierz

for / in 은 해시테이블(연관 배열)과 배열(비연관)의 두 가지 유형의 변수와 함께 작동합니다.

JavaScript는 항목을 통과하는 방법을 자동으로 결정합니다. 따라서 배열이 실제로 비연관적이라는 것을 알고 있다면 for (var i=0; i<=arrayLen; i++) 를 사용하고 자동 감지 반복을 건너뛸 수 있습니다.

for / in 을 사용하는 것이 더 낫습니다. 자동 감지에 필요한 프로세스는 매우 적습니다.

이에 대한 실제 답은 브라우저가 JavaScript 코드를 어떻게 파서/해석하는지에 달려 있습니다. 브라우저 간에 변경될 수 있습니다.

for / in 사용하지 않는 다른 목적을 생각할 수 없습니다.

 //Non-associative var arr = ['a', 'b', 'c']; for (var i in arr) alert(arr[i]); //Associative var arr = { item1 : 'a', item2 : 'b', item3 : 'c' }; for (var i in arr) alert(arr[i]);

Ricardo

조심하지 않으면 프로토타입 체인의 객체에 속한 속성을 반복하기 때문입니다.

for.. in 사용할 수 있습니다. 각 속성을 hasOwnProperty로 확인하십시오.


JAL

그것이 반드시 나쁜 것은 아니지만(당신이 하는 일에 따라), 배열의 경우, Array.prototype 무언가가 추가되면 이상한 결과를 얻게 될 것입니다. 이 루프가 세 번 실행될 것으로 예상되는 위치:

 var arr = ['a','b','c']; for (var key in arr) { ... }

라는 함수 경우 helpfulUtilityMethod 추가되었습니다 Arrayprototype , 다음 루프 네 번 실행 끝낼 것 : key 될 것이다 0 , 1 , 2 , 및 helpfulUtilityMethod . 정수만 기대했다면 죄송합니다.


josh3736

객체가 아닌 속성 목록에서만 for(var x in y) 사용해야 합니다(위에서 설명한 대로).


user268396

이것이 (일반적으로) 나쁜 습관인 이유는 다음과 같습니다.

  1. for...in 루프는 자신의 모든 열거 가능한 속성 프로토타입의 열거 가능한 속성을 반복합니다. 일반적으로 배열 반복에서 우리는 배열 자체에 대해서만 반복하기를 원합니다. 그리고 자신이 어레이에 아무것도 추가하지 않더라도 라이브러리나 프레임워크에서 추가할 수 있습니다.

:

 Array.prototype.hithere = 'hithere'; var array = [1, 2, 3]; for (let el in array){ // the hithere property will also be iterated over console.log(el); }

  1. for...in 루프 는 특정 반복 순서를 보장하지 않습니다 . 오늘날 대부분의 최신 브라우저에서 일반적으로 순서가 표시되지만 여전히 100% 보장은 없습니다.
  2. for...in 루프는 undefined 배열 요소, 즉 아직 할당되지 않은 배열 요소를 무시합니다.

예: :

 const arr = []; arr[3] = 'foo'; // resize the array to 4 arr[4] = undefined; // add another element with value undefined to it // iterate over the array, a for loop does show the undefined elements for (let i = 0; i < arr.length; i++) { console.log(arr[i]); } console.log('\n'); // for in does ignore the undefined elements for (let el in arr) { console.log(arr[el]); }


Willem van der Veen

for...in 루프를 사용하는 것은 잘못된 것이 아니지만 누군가가 다음과 같이 말한 이유를 추측할 수 있습니다.

1.) 배열에 대해 그 목적을 가지고 있지만 'forEach'라고 하는 더 많은 기능과 간결한 구문을 가진 고차 함수 또는 메서드가 이미 있습니다. Array.prototype.forEach(function(element, index, array) {} );

2.) 배열에는 항상 길이가 있지만 for...inforEach 'undefined' 값에 대해 함수를 실행하지 않고 값이 정의된 인덱스에 대해서만 실행합니다. 따라서 하나의 값만 할당하면 이 루프는 함수를 한 번만 실행하지만 배열이 열거되기 때문에 항상 정의된 값이 있는 가장 높은 인덱스까지의 길이를 가지지만 이러한 길이를 사용할 때 그 길이는 눈에 띄지 않을 수 있습니다. 루프.

3.) 표준 for 루프는 매개변수에 정의한 횟수만큼 함수를 실행하며, 배열에는 번호가 매겨져 있으므로 함수를 실행할 횟수를 정의하는 것이 더 합리적입니다. 다른 루프와 달리 for 루프는 값이 정의되었는지 여부에 관계없이 배열의 모든 인덱스에 대해 함수를 실행할 수 있습니다.

본질적으로 모든 루프를 사용할 수 있지만 작동 방식을 정확히 기억해야 합니다. 서로 다른 루프가 반복되는 조건과 각 루프의 개별 기능을 이해하고 서로 다른 시나리오에 다소 적절할 것임을 인식합니다.

for...in 루프보다 forEach 메서드를 사용하는 것이 더 나은 방법으로 간주될 수 있습니다. 작성이 더 쉽고 더 많은 기능을 가지므로 이 메서드만 사용하는 습관을 들이고 싶을 수도 있습니다. 및 표준이지만 귀하의 부름.

아래에서 처음 두 루프는 console.log 문을 한 번만 실행하는 반면 for 루프는 지정된 횟수만큼 함수를 실행합니다(이 경우 array.length = 6).

 var arr = []; arr[5] = 'F'; for (var index in arr) { console.log(index); console.log(arr[index]); console.log(arr) } // 5 // 'F' // => (6) [undefined x 5, 6] arr.forEach(function(element, index, arr) { console.log(index); console.log(element); console.log(arr); }); // 5 // 'F' // => Array (6) [undefined x 5, 6] for (var index = 0; index < arr.length; index++) { console.log(index); console.log(arr[index]); console.log(arr); }; // 0 // undefined // => Array (6) [undefined x 5, 6] // 1 // undefined // => Array (6) [undefined x 5, 6] // 2 // undefined // => Array (6) [undefined x 5, 6] // 3 // undefined // => Array (6) [undefined x 5, 6] // 4 // undefined // => Array (6) [undefined x 5, 6] // 5 // 'F' // => Array (6) [undefined x 5, 6]

mrmaclean89

for...in 루프는 항상 키를 열거합니다. 객체 속성 키는 배열의 인덱싱된 속성을 포함하여 항상 String입니다.

 var myArray = ['a', 'b', 'c', 'd']; var total = 0 for (elem in myArray) { total += elem } console.log(total); // 00123

Maher Tliba

for...in 은 JavaScript에서 객체에 대해 작업할 때 유용하지만 Array에는 유용하지 않지만 여전히 잘못된 방법이라고 말할 수는 없지만 권장되지는 않습니다. for...in 루프를 사용하는 아래 예제를 살펴보세요.

 let txt = ""; const person = {fname:"Alireza", lname:"Dezfoolian", age:35}; for (const x in person) { txt += person[x] + " "; } console.log(txt); //Alireza Dezfoolian 35

자, 이제 Array를 사용해 보겠습니다.

 let txt = ""; const person = ["Alireza", "Dezfoolian", 35]; for (const x in person) { txt += person[x] + " "; } console.log(txt); //Alireza Dezfoolian 35

결과를 보시면 아시겠지만...

하지만 뭔가를 시도해 봅시다. Array에 프로토타입을 만들어 봅시다...

 Array.prototype.someoneelse = "someoneelse";

이제 새 Array()를 만듭니다.

 let txt = ""; const arr = new Array(); arr[0] = 'Alireza'; arr[1] = 'Dezfoolian'; arr[2] = 35; for(x in arr) { txt += arr[x] + " "; } console.log(txt); //Alireza Dezfoolian 35 someoneelse

당신은 누군가를 봅니다 !!!... 우리는 실제로 이 경우에 새로운 Array 객체를 반복합니다!

이것이 우리가 for..in을 주의 깊게 사용해야 하는 이유 중 하나이지만 항상 그런 것은 아닙니다...


Alireza

JavaScript 요소는 표준 개체 속성으로 저장되므로 for...in 루프를 사용하여 JavaScript 배열을 반복하는 것은 권장되지 않습니다. 일반 요소와 모든 열거 가능한 속성이 나열되기 때문입니다.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Indexed_collections에서


Badr Elmers

NodeList 와 함께 for...in을 사용하지 않는 데는 아주 좋은 이유가 있다고 querySelectorAll , 대신 NodeList 속성에 대해서만 반복합니다.

단일 결과의 경우 다음을 얻었습니다.

 var nodes = document.querySelectorAll(selector); nodes ▶ NodeList [a._19eb] for (node in nodes) {console.log(node)}; VM505:1 0 VM505:1 length VM505:1 item VM505:1 entries VM505:1 forEach VM505:1 keys VM505:1 values

my for (node in nodes) node.href = newLink; 실패했다.


jcomeau_ictx

출처 : http:www.stackoverflow.com/questions/500504/why-is-using-for-in-for-array-iteration-a-bad-idea

반응형