¿Cuál es la diferencia entre (para ... en) y (para ... de) declaraciones en JavaScript?

410

Sé lo que es el for... inbucle (itera sobre la clave), pero escuché la primera vez sobre for... of(itera sobre el valor).

Estoy confundido con for... ofloop. No recibí adjetivo. Este es el código a continuación:

var arr = [3, 5, 7];
arr.foo = "hello";

for (var i in arr) {
  console.log(i); // logs "0", "1", "2", "foo"
}

for (var i of arr) {
  console.log(i); // logs "3", "5", "7"
  // it is does not log "3", "5", "7", "hello"
}

Lo que obtuve es, for... ofitera sobre los valores de propiedad. Entonces, ¿por qué no registra (regresa) en "3", "5", "7", "hello"lugar de "3", "5", "7"? pero el for... inciclo itera sobre cada tecla ( "0", "1", "2", "foo"). Aquí el for... inciclo también itera sobre la fooclave. Pero for... ofno itera sobre el valor de la foopropiedad, es decir "hello". ¿Por qué es así?

Larga historia en resumen:

Aquí tengo un for... ofbucle de consola . Debe iniciar sesión "3", "5", "7","hello"pero aquí se registra "3", "5", "7". Por qué ?

Enlace de ejemplo

Mukund Kumar
fuente
1
en caso de que te lo pierdas, aquí está el enlace de inicio developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Anthony Russell
1
En lo que respecta a mi comprensión, for ... ofse introdujo en el idioma para solucionar los problemas de uso for ... incon matrices. Array.prototypepodría modificarse de tal manera que haya propiedades adicionales disponibles, lo que hace que no sea seguro iterarlas, ya que podría obtener claves no numéricas que no esperaba.
Phylogenesis
2
Para futuros lectores: esto probablemente no sea un duplicado de la palabra clave JavaScript of(para ... de bucles) , ya que pregunta sobre un comportamiento específico de la función, en lugar de pedir una descripción general.
apsillers
2
for <key> infor <value> offor..of
Acostúmbrate
Gran artículo sobre medium
Kalhan.Toress

Respuestas:

304

for in recorre los nombres de propiedad enumerables de un objeto.

for of(nuevo en ES6) usa un iterador específico de objeto y recorre los valores generados por eso.

En su ejemplo, el iterador de matriz produce todos los valores en la matriz (ignorando las propiedades que no son de índice).

Bergi
fuente
99
for ... ofestá estandarizado en ES6.
Justin
2
Eso es extraño, juro que leí en alguna parte que se mudó de nuevo a ES7, pero aparentemente eso no era cierto. Culpa mía.
Alexander O'Mara
40
Una mnemónica: 'o'f -> no' o'bjects, 'i'n -> not' i'terables
Placoplatr
44
otro mnemónico: for... of:: arrays :: los arrays siempre tienen una longitud, por lo que puede pensar for.. [elemento n] of.. [elementos q]
Nathan Smith
14
Otra mnemónica ... for..in..keys=== claves foráneas === uso for...inpara claves! Como tal, use for...ofpara los valores.
Gunther
237

Encuentro una respuesta completa en: https://www.typescriptlang.org/docs/handbook/iterators-and-generators.html (aunque es para script tipo, esto es lo mismo para javascript también)

Ambas declaraciones for..ofy se for..inrepiten en las listas; sin embargo, los valores iterados son diferentes, for..indevuelve una lista de claves en el objeto que se está iterando, mientras que for..ofdevuelve una lista de valores de las propiedades numéricas del objeto que se está iterando.

Aquí hay un ejemplo que demuestra esta distinción:

let list = [4, 5, 6];

for (let i in list) {
   console.log(i); // "0", "1", "2",
}

for (let i of list) {
   console.log(i); // "4", "5", "6"
}

Otra distinción es que for..in opera en cualquier objeto; Sirve como una forma de inspeccionar las propiedades de este objeto. for..ofpor otro lado, está principalmente interesado en valores de objetos iterables. Objetos incorporados como Map y Set que implement Symbol.iteratorpermiten el acceso a los valores almacenados

let pets = new Set(["Cat", "Dog", "Hamster"]);
pets["species"] = "mammals";

for (let pet in pets) {
   console.log(pet); // "species"
}

for (let pet of pets) {
    console.log(pet); // "Cat", "Dog", "Hamster"
}
Alireza Fattahi
fuente
1
Además, llamar a algo como for (let i of {}) {console.log (i); } lanzaría un TypeError: VM391: 1 TypeError no capturado: {} no es iterable en <anónimo>: 1: 14, al menos en Chrome
kboom
TS para la victoria: el ejemplo es incorrecto, este último debe devolver "mamíferos", no // "Gato", "Perro", "Hámster"
martinp999
8
Lo recuerdo por: para "en" para index. Y luego para "de" sería el valuesde cada índice / clave / elemento.
SherylHohman
Bien, esto va a ser el rey para mí: usar for-ins para la iteración de elementos que generalmente tengo que crear una let thisItem = items[all];variable, ¡ for...ofayuda a atajar eso!
Vasily Hall
Lo recuerdo por: for...incomo Object.keys(), ¿adivina qué? Las matrices son objetos, algo que también devolvería sus indeces. :)
Sujeet Agrahari
38

Para ... en bucle

El bucle for ... in mejora las debilidades del bucle for al eliminar la lógica de conteo y la condición de salida.

Ejemplo:

const digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

for (const index in digits) {
  console.log(digits[index]);
}

Pero, aún tiene que lidiar con el problema de usar un índice para acceder a los valores de la matriz, y eso apesta; casi lo hace más confuso que antes.

Además, el bucle for ... in puede meterlo en grandes problemas cuando necesita agregar un método adicional a una matriz (u otro objeto). Debido a que ... en bucles recorren todas las propiedades enumerables, esto significa que si agrega propiedades adicionales al prototipo de la matriz, esas propiedades también aparecerán en el bucle.

Array.prototype.decimalfy = function() {
  for (let i = 0; i < this.length; i++) {
    this[i] = this[i].toFixed(2);
  }
};

const digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

for (const index in digits) {
  console.log(digits[index]);
}

Huellas dactilares:

0 0

1

2

3

4 4

5 5

6 6

7 7

8

9 9

function () {for (let i = 0; i <this.length; i ++) {this [i] = this [i] .toFixed (2); }}

Esta es la razón por la cual se desaconseja ... en bucles cuando se repite en matrices.

NOTA : El bucle forEach es otro tipo de bucle for en JavaScript. Sin embargo, en forEach()realidad es un método de matriz, por lo que solo se puede usar exclusivamente con matrices. Tampoco hay forma de detener o romper un ciclo forEach. Si necesita ese tipo de comportamiento en su ciclo, tendrá que usar un ciclo básico para.

Para ... de bucle

El for ... of loop se usa para recorrer cualquier tipo de datos que sea iterable.

Ejemplo:

const digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

for (const digit of digits) {
  console.log(digit);
}

Huellas dactilares:

0 0

1

2

3

4 4

5 5

6 6

7 7

8

9 9

Esto hace que for ... of loop sea la versión más concisa de todos los bucles for.

¡Pero espera hay mas! El bucle for ... of también tiene algunos beneficios adicionales que solucionan las debilidades del for y for ... en los bucles.

Puede detener o romper un bucle for ... en cualquier momento.

const digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

for (const digit of digits) {
  if (digit % 2 === 0) {
    continue;
  }
  console.log(digit);
}

Huellas dactilares:

1

3

5 5

7 7

9 9

Y no tiene que preocuparse por agregar nuevas propiedades a los objetos. El for ... of loop solo recorrerá los valores del objeto.

Elar
fuente
2
" El bucle for ... in mejora las debilidades del bucle for al eliminar la lógica de conteo y la condición de salida " - no, eso no es lo que hace. De ningún modo.
Bergi
1
@Bergi ¿Podrías aclarar por qué crees que eso no es lo que hace y en qué crees que mejora?
Elar
2
No mejora en nada, tiene su propia razón de ser. Hace algo totalmente diferente a un for (var index=0; index<arr.length; index++)bucle (donde el indexcontador es un entero, a diferencia de su ejemplo).
Bergi
hace que sea confuso que los valores de la matriz que elija para el ejemplo correspondan con los valores del índice de la matriz ...
Sergey
20

Diferencia for..iny for..of:

Tanto for..iny for..ofestán bucle constructos que se utilizan para iterar sobre estructuras de datos. La única diferencia es sobre lo que iteran:

  1. for..initera sobre todas las claves de propiedad enumerables de un objeto
  2. for..of itera sobre el valores de un objeto iterable. Ejemplos de objetos iterables son matrices, cadenas y listas de nodos.

Ejemplo:

let arr = ['el1', 'el2', 'el3'];

arr.addedProp = 'arrProp';

// elKey are the property keys
for (let elKey in arr) {
  console.log(elKey);
}

// elValue are the property values
for (let elValue of arr) {
  console.log(elValue)
}

En este ejemplo, podemos observar que el for..inbucle itera sobre las teclas del objeto, que es un objeto de matriz en este ejemplo. Las claves son 0, 1, 2 que corresponden a los elementos de la matriz que agregamos y addedProp. Así es como se arrve el objeto de matriz en devtools de Chrome:

ingrese la descripción de la imagen aquí

Ves que nuestro for..in bucle no hace más que simplemente iterar sobre estos valores.


El for..ofbucle en nuestro ejemplo itera sobre los valores de una estructura de datos. Los valores en este ejemplo específico son 'el1', 'el2', 'el3'. Los valores que devolverá una estructura de datos iterable for..ofdependen del tipo de objeto iterable. Por ejemplo, una matriz devolverá los valores de todos los elementos de la matriz, mientras que una cadena devuelve cada carácter individual de la cadena.

Willem van der Veen
fuente
8

La for...indeclaración itera sobre las propiedades enumerables de un objeto, en un orden arbitrario. Las propiedades enumerables son aquellas propiedades cuyo indicador interno [[Enumerable]] se establece en verdadero, por lo tanto, si hay alguna propiedad enumerable en la cadena del prototipo, el for...inciclo también se repetirá en ellas.

La for...ofdeclaración itera sobre los datos que el objeto iterable define para iterar.

Ejemplo:

Object.prototype.objCustom = function() {}; 
Array.prototype.arrCustom = function() {};

let iterable = [3, 5, 7];

for (let i in iterable) {
  console.log(i); // logs: 0, 1, 2, "arrCustom", "objCustom"
}

for (let i in iterable) {
  if (iterable.hasOwnProperty(i)) {
    console.log(i); // logs: 0, 1, 2,
  }
}

for (let i of iterable) {
  console.log(i); // logs: 3, 5, 7
}

Al igual que antes, se puede omitir la adición hasOwnPropertyde for...ofbucles.

Ramandeep Sohi
fuente
7

La instrucción for-in itera sobre las propiedades enumerables de un objeto, en orden arbitrario.

El ciclo iterará sobre todas las propiedades enumerables del objeto mismo y aquellas que el objeto hereda del prototipo de su constructor.

Puedes considerarlo "for in" básicamente itera y enumera todas las claves.

var str = 'abc';
var arrForOf = [];
var arrForIn = [];

for(value of str){
  arrForOf.push(value);
}

for(value in str){
  arrForIn.push(value);
}

console.log(arrForOf); 
// ["a", "b", "c"]
console.log(arrForIn); 
// ["0", "1", "2", "formatUnicorn", "truncate", "splitOnLast", "contains"]
Devdutta Natu
fuente
for in solo mostrará las claves si las agregamos, no mostrará formatoUnicornio
Milad
1
"formatUnicorn", "truncate", "splitOnLast", "contiene" print out porque stackoverflow override String.prototype.
jasonxia23
6

Hay algunos tipos de datos ya definidos que nos permiten iterar sobre ellos fácilmente, por ejemplo, Array, Map, String Objects

Normal for in itera sobre el iterador y en respuesta nos proporciona las claves que están en el orden de inserción como se muestra en el siguiente ejemplo.

  const numbers = [1,2,3,4,5];
   for(let number in number) {
     console.log(number);
   }

   // result: 0, 1, 2, 3, 4

Ahora, si intentamos lo mismo con for of , en respuesta nos proporciona los valores, no las claves. p.ej

  const numbers = [1,2,3,4,5];
   for(let numbers of numbers) {
    console.log(number);
  }

  // result: 1, 2, 3, 4, 5

Entonces, mirando ambos iteradores, podemos diferenciar fácilmente la diferencia entre ambos.

Nota: - Para de sólo funciona con la Symbol.iterator

Entonces, si tratamos de iterar sobre un objeto normal, entonces nos dará un error, por ejemplo:

const Room = {
   area: 1000,
   height: 7,
   floor: 2
 }

for(let prop in Room) {
 console.log(prop);
 } 

// Result area, height, floor

for(let prop of Room) {
  console.log(prop);
 } 

La habitación no es iterable

Ahora, para iterar, necesitamos definir un ES6 Symbol.iterator ej.

  const Room= {
    area: 1000, height: 7, floor: 2,
   [Symbol.iterator]: function* (){
    yield this.area;
    yield this.height;
    yield this.floors;
  }
}


for(let prop of Room) {
  console.log(prop);
 } 

//Result 1000, 7, 2

Esta es la diferencia entre For in y For of . Espero que pueda aclarar la diferencia.

Amit Mundra
fuente
5

Otra diferencia entre los dos bucles, que nadie ha mencionado antes:

La desestructuración for...inestá en desuso. Usar en su for...oflugar.

Fuente

Entonces, si queremos usar la desestructuración en un bucle, para obtener tanto el índice como el valor de cada elemento de la matriz , debemos usar el for...ofbucle con el método Arrayentries() :

for (const [idx, el] of arr.entries()) {
    console.log( idx + ': ' + el );
}
simhumileco
fuente
1
Sí @GalMargalit, lo leí cuidadosamente. Estoy de acuerdo en que for each...inestá en desuso (primer punto), pero no escribí sobre eso ... Escribí que "La desestructuración for...inestá en desuso. Use en su for...oflugar". (segundo punto): developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… ¿Está de acuerdo conmigo @GalMargalit?
simhumileco
1
Jaja tienes razón, no leí con cuidado! Es cierto, básicamente estaba pensando lo mismo y pensé que te referías a otro.
Gal Margalit
2

Todos explicaron por qué ocurre este problema, pero aún así es muy fácil olvidarlo y luego rascarse la cabeza por qué obtuviste resultados incorrectos. Especialmente cuando trabajas en grandes conjuntos de datos cuando los resultados parecen estar bien a primera vista.

Utilizándote Object.entriesasegúrate de recorrer todas las propiedades:

var arr = [3, 5, 7];
arr.foo = "hello";

for ( var [key, val] of Object.entries( arr ) ) {
   console.log( val );
}

/* Result:

3
5
7
hello

*/
David C.
fuente
2

Veo muchas buenas respuestas, pero decido poner mis 5 centavos solo para tener un buen ejemplo:

Para en bucle

itera sobre todos los accesorios enumerables

let nodes = document.documentElement.childNodes;

for (var key in nodes) {
  console.log( key );
}

Para de bucle

itera sobre todos los valores iterables

let nodes = document.documentElement.childNodes;

for (var node of nodes) {
  console.log( node.toString() );
}

WebBrother
fuente
2

Cuando comencé a aprender el bucle for in y of , también estaba confundido con mi salida, pero con un par de investigaciones y comprensión puedes pensar en el bucle individual de la siguiente manera:

  1. for ... in loop devuelve los índices de la propiedad individual y no tiene ningún efecto de impacto en el valor de la propiedad , realiza un bucle y devuelve información sobre la propiedad y no el valor . P.ej

let profile = { name : "Naphtali", age : 24, favCar : "Mustang", favDrink : "Baileys" }

El código anterior solo está creando un objeto llamado perfil , lo usaremos para nuestros dos ejemplos , así que no se confunda cuando vea el objeto de perfil en un ejemplo, solo sepa que fue creado.

Así que ahora usemos el for ... en bucle siguiente

for(let myIndex in profile){
    console.log(`The index of my object property is ${myIndex}`)
}
 // Outputs : 
        The index of my object property is 0
        The index of my object property is 1
        The index of my object property is 2
        The index of my object property is 3

Ahora, la razón de la salida es que tenemos cuatro (4) propiedades en nuestro objeto de perfil y la indexación, como todos sabemos, comienza desde 0 ... n , por lo tanto, obtenemos el índice de propiedades 0,1,2,3 ya que estamos trabajando con el for..in loop.

  1. for ... of loop * puede devolver la propiedad , valor o ambos , echemos un vistazo a cómo. En javaScript, no podemos recorrer los objetos normalmente como lo haríamos en matrices, por lo tanto, hay algunos elementos que podemos usar para acceder a cualquiera de nuestras elecciones desde un objeto.

    • Object.keys ( object-name-goes-here ) >>> Devuelve las claves o propiedades de un objeto.

    • Object.values ( object-name-goes-here ) >>> Devuelve los valores de un objeto.

    • Object.entries ( object-name-goes-here ) >>> Devuelve tanto las claves como los valores de un objeto.

A continuación se muestran ejemplos de su uso, preste atención a Object.entries () :

Step One: Convert the object to get either its key, value, or both.
Step Two: loop through.


// Getting the keys/property

   Step One: let myKeys = ***Object.keys(profile)***
   Step Two: for(let keys of myKeys){
             console.log(`The key of my object property is ${keys}`)
           }

// Getting the values of the property

    Step One: let myValues = ***Object.values(profile)***
    Step Two : for(let values of myValues){
                 console.log(`The value of my object property is ${values}`)
               }

Cuando use Object.entries () tenga en cuenta que está llamando a dos entradas en el objeto, es decir , las claves y los valores. Puede llamar a ambos por cualquiera de las entradas. Ejemplo a continuación.

Step One: Convert the object to entries, using ***Object.entries(object-name)***
Step Two: **Destructure** the ***entries object which carries the keys and values*** 
like so **[keys, values]**, by so doing, you have access to either or both content.


    // Getting the keys/property

       Step One: let myKeysEntry = ***Object.entries(profile)***
       Step Two: for(let [keys, values] of myKeysEntry){
                 console.log(`The key of my object property is ${keys}`)
               }

    // Getting the values of the property

        Step One: let myValuesEntry = ***Object.entries(profile)***
        Step Two : for(let [keys, values] of myValuesEntry){
                     console.log(`The value of my object property is ${values}`)
                   }

    // Getting both keys and values

        Step One: let myBothEntry = ***Object.entries(profile)***
        Step Two : for(let [keys, values] of myBothEntry){
                     console.log(`The keys of my object is ${keys} and its value 
is ${values}`)
                   }

Haga comentarios sobre secciones de piezas poco claras.

Neftalí Duniya
fuente
1

El for-inbucle

for-inEl bucle se utiliza para recorrer las propiedades enumerables de una colección, en un orden arbitrario . Una colección es un objeto de tipo contenedor cuyos elementos pueden estar usando un índice o una clave.

var myObject = {a: 1, b: 2, c: 3};
var myArray = [1, 2, 3];
var myString = "123";

console.log( myObject[ 'a' ], myArray[ 1 ], myString[ 2 ] );

for-inloop extrae todas las propiedades enumerables ( claves ) de una colección de una vez y las repite una por una. Una propiedad enumerable es la propiedad de una colección que puede aparecer en for-inbucle.

Por defecto, todas las propiedades de una matriz y un objeto aparecen en for-inbucle. Sin embargo, podemos usar el método Object.defineProperty para configurar manualmente las propiedades de una colección.

var myObject = {a: 1, b: 2, c: 3};
var myArray = [1, 2, 3];

Object.defineProperty( myObject, 'd', { value: 4, enumerable: false } );
Object.defineProperty( myArray, 3, { value: 4, enumerable: false } );

for( var i in myObject ){ console.log( 'myObject:i =>', i ); }
for( var i in myArray ){ console.log( 'myArray:i  =>', i ); }

En el ejemplo anterior, la propiedad dde myObjecty el índice 3de myArrayno aparece en el for-inbucle porque están configurados conenumerable: false .

Hay pocos problemas con los for-inbucles. En el caso de matrices, for-inloop también considerarámethods agregado en la matriz usando la myArray.someMethod = fsintaxis, sin embargo, myArray.lengthpermanece4 .

los for-ofbucle

Es una idea errónea que el for-ofciclo itera sobre los valores de una colección.for-ofel ciclo itera sobre un Iterableobjeto. Un iterable es un objeto que tiene el método con el nombre Symbol.iteratordirectamente en uno de sus prototipos.

Symbol.iteratorEl método debe devolver un iterador . Un iterador es un objeto que tiene unnext método. Este método cuando se llama return valueydone propiedades.

Cuando iteramos un objeto iterable usando un for-ofbucle, Symbol.iteratorse llamará al método una vez que obtengamos un objeto iterador . Para cada iteración del for-ofbucle, nextse llamará al método de este objeto iterador hasta que donela next()llamada devuelva falso. El valor recibido por el for-ofciclo para cada iteración si la valuepropiedad devuelve la next()llamada.

var myObject = { a: 1, b: 2, c: 3, d: 4 };

// make `myObject` iterable by adding `Symbol.iterator` function directlty on it
myObject[ Symbol.iterator ] = function(){
  console.log( `LOG: called 'Symbol.iterator' method` );
  var _myObject = this; // `this` points to `myObject`
  
  // return an iterator object
  return {
    keys: Object.keys( _myObject ), 
    current: 0,
    next: function() {
      console.log( `LOG: called 'next' method: index ${ this.current }` );
      
      if( this.current === this.keys.length ){
        return { done: true, value: null }; // Here, `value` is ignored by `for-of` loop
      } else {
        return { done: false, value: _myObject[ this.keys[ this.current++ ] ] };
      }
    }
  };
}

// use `for-of` loop on `myObject` iterable
for( let value of myObject ) {
  console.log( 'myObject: value => ', value );
}

El for-ofciclo es nuevo en ES6 y también lo son Iterable e Iterables . El Arraytipo de constructor tiene Symbol.iteratormétodo en su prototipo. El Objectconstructor lamentablemente no lo tiene Object.keys(), Object.values()y los Object.entries()métodos devuelven un iterable ( puede usar console.dir(obj)para verificar los métodos prototipo ). El beneficio del for-ofbucle es que cualquier objeto puede hacerse iterable, incluso sus clases Dogy su costumbre Animal.

La manera fácil de hacer que un objeto sea iterable es implementar ES6 Generator en lugar de la implementación personalizada del iterador.

A diferencia for-in, el for-ofbucle puede esperar a que se complete una tarea asíncrona en cada iteración. Esto se logra usando la awaitpalabra clave después de la documentación de lafor declaración .

Otra gran cosa sobre for-ofloop es que tiene soporte Unicode. Según las especificaciones de ES6, las cadenas se almacenan con codificación UTF-16. Por lo tanto, cada personaje puede tomar uno 16-bito 32-bit. Tradicionalmente, las cadenas se almacenaban con codificación UCS-2 que tiene soporte para caracteres que solo se pueden almacenar dentro 16 bits.

Por lo tanto, String.lengthdevuelve el número de 16-bitbloques en una cadena. Los personajes modernos como un personaje Emoji toman 32 bits. Por lo tanto, este carácter devolvería length2. el for-inciclo itera sobre los 16-bitbloques y devuelve el error index. Sin embargo, el for-ofciclo itera sobre el carácter individual basado en las especificaciones UTF-16.

var emoji = "😊🤣";

console.log( 'emoji.length', emoji.length );

for( var index in emoji ){ console.log( 'for-in: emoji.character', emoji[index] ); }
for( var character of emoji ){ console.log( 'for-of: emoji.character', character ); }

Uday Hiwarale
fuente
0

Encontré la siguiente explicación de https://javascript.info/array muy útil:

Una de las formas más antiguas de ciclo de los elementos de la matriz es el ciclo for over over indexes:

let arr = ["Apple", "Orange", "Pear"];

for (let i = 0; i < arr.length; i++) { alert( arr[i] ); } But for arrays there is another form of loop, for..of:

let fruits = ["Apple", "Orange", "Plum"];

// iterates over array elements for (let fruit of fruits) { alert( fruit ); } The for..of doesn’t give access to the number of the current element, just its value, but in most cases that’s enough. And it’s shorter.

Técnicamente, debido a que las matrices son objetos, también es posible usar para..in:

let arr = ["Apple", "Orange", "Pear"];

for (let key in arr) { alert( arr[key] ); // Apple, Orange, Pear } But that’s actually a bad idea. There are potential problems with it:

El ciclo for..in itera sobre todas las propiedades, no solo las numéricas.

Existen los llamados objetos "tipo matriz" en el navegador y en otros entornos, que parecen matrices. Es decir, tienen propiedades de longitud e índices, pero también pueden tener otras propiedades y métodos no numéricos, que generalmente no necesitamos. Sin embargo, el bucle for..in los enumerará. Entonces, si necesitamos trabajar con objetos tipo matriz, entonces estas propiedades "adicionales" pueden convertirse en un problema.

El bucle for..in está optimizado para objetos genéricos, no para matrices, y por lo tanto es 10-100 veces más lento. Por supuesto, sigue siendo muy rápido. La aceleración solo puede importar en cuellos de botella. Pero aún así debemos ser conscientes de la diferencia.

En general, no deberíamos usar for..in para matrices.

Albert Leung
fuente
0

Aquí hay un mnemónico útil para recordar la diferencia entre for...inLoop y for...ofLoop.

"indexar, objeto de"

for...in Loop=> itera sobre el índice en la matriz.

for...of Loop=> itera sobre el objeto de los objetos.

Bnieland
fuente