switch - Bucles de JavaScript: para... en vs para
switch javascript (4)
for(var key in obj) { }
itera sobre todos los elementos en el objeto, incluidos los de sus prototipos. Entonces, si lo está usando y no puede saber nada del Object.prototype
extendido, siempre debe probar obj.hasOwnProperty(key)
y omitir la clave si esta verificación devuelve falso.
for(start; continuation; loop)
es un bucle de estilo C: el start
se ejecuta antes del bucle, la continuation
se prueba y el bucle solo continúa mientras es verdadero, el loop
se ejecuta después de cada bucle.
Enfrenté un comportamiento extraño en Javascript. yo obtengo
"El objeto no admite esta propiedad o método"
excepción para la función removeAttribute
en el siguiente código:
var buttons = controlDiv.getElementsByTagName("button");
for ( var button in buttons )
button.removeAttribute(''disabled'');
Cuando cambio el código con lo siguiente, el problema desaparece:
var buttons = controlDiv.getElementsByTagName("button");
for ( var i = 0; i < buttons.length; i++ )
buttons[i].removeAttribute(''disabled'');
¿Cuál es el valor del button
dentro del for...in
?
for...in
se utilizará cuando desee recorrer las propiedades de un objeto. Pero funciona igual que un ciclo for
normal: la variable loop contiene el "índice" actual, es decir, la propiedad del objeto y no el valor.
Para iterar sobre las matrices, debe usar un ciclo for
normal. buttons
no es una matriz, sino una NodeList
(una estructura similar a una matriz).
Si itera sobre los buttons
con for...in
con:
for(var i in a) {
console.log(i)
}
Verás que produce algo así como:
1
2
...
length
item
porque la length
y el item
son dos propiedades de un objeto de tipo NodeList
. Entonces, si usa ingenuamente para ... for..in
, intentaría acceder a los buttons[''length''].removeAttribute()
que emitirá un error ya que los buttons[''length'']
es una función y no un elemento DOM.
Entonces, la forma correcta es usar un ciclo for
normal. Pero hay otro problema:
NodeList
están NodeList
, lo que significa que cada vez que acceda, por ejemplo, a la length
, la lista se actualiza (los elementos se buscan de nuevo). Por lo tanto, debe evitar llamadas innecesarias a la length
.
Ejemplo:
for(var i = 0, l = buttons.length; i < l, i++)
No use for..in
para la iteración de Array.
Es importante comprender que la sintaxis de corchetes cuadrados de Javascript Array ( []
) para acceder a indices se hereda del Object
...
obj.prop === obj[''prop''] // true
La estructura de for..in
no funciona como una forma más tradicional de ... cada for..each/in
que se encontraría en otros idiomas (php, python, etc.).
Javascript for..in
está diseñado para iterar sobre las propiedades de un objeto . Produciendo la clave de cada propiedad. Al usar esta tecla combinada con la sintaxis del soporte del Object
, puede acceder fácilmente a los valores que está buscando.
var obj = {
foo: "bar",
fizz: "buzz",
moo: "muck"
};
for ( var prop in obj ) {
console.log(prop); // foo / fizz / moo
console.log(obj[prop]); // bar / buzz / muck
}
Y debido a que el Array es simplemente un Objeto con nombres de propiedades numéricas secuenciales (índices), el for..in
funciona de manera similar, produciendo los indicios numéricos tal como produce los nombres de propiedades anteriores.
Una característica importante de la estructura for..in
es que continúa buscando propiedades enumerables en la cadena de prototipos. También iterará las propiedades enumerables heredadas . hasOwnProperty()
usted verificar que la propiedad actual exista directamente en el objeto local y no el prototipo al que está asociada con hasOwnProperty()
...
for ( var prop in obj ) {
if ( obj.hasOwnProperty(prop) ) {
// prop is actually obj''s property (not inherited)
}
}
( Más sobre la herencia prototípica )
El problema con el uso de la estructura for..in
en el tipo de matriz es que no hay ningún usuario en cuanto al orden en que se producen las propiedades ... y, en términos generales, esa es una característica muy importante en el procesamiento de una matriz.
Otro problema es que generalmente es más lento que un estándar for
implementación.
Línea de fondo
Usar un for...in
para iterar matrices es como usar la culata de un destornillador para clavar un clavo ... ¿por qué no usarías un martillo ( for
)?
Mientras que for..in no debería usarse generalmente para Arrays, sin embargo antes de ES5 hubo un caso para usarlo con matrices dispersas.
Como se señaló en otras respuestas, los problemas principales con for..in y Arrays son:
- Las propiedades no se devuelven necesariamente en orden (es decir, no 0, 1, 2, etc.)
- Se devuelven todas las propiedades enumerables, incluidas las propiedades que no son índice y las de la cadena
[[Prototype]]
. Esto lleva a un rendimiento menor ya que es probable que se requiera una prueba de hasOwnProperty para evitar las propiedades heredadas.
Una de las razones para usar ... antes de ES5 era mejorar el rendimiento con matrices dispersas, siempre que el orden no importara. Por ejemplo, en lo siguiente:
var a = [0];
a[1000] = 1;
Iterar sobre un uso para ... será mucho más rápido que usar un bucle for, ya que solo visitará dos propiedades, mientras que un bucle for intentará con 1001.
Sin embargo, este caso es redundante para ESE para forEach , que solo visita miembros que existen, entonces:
a.forEach();
también solo iterará sobre dos propiedades, en orden.