1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
|
---
title: for...in
slug: Web/JavaScript/Reference/Statements/for...in
tags:
- Característica del lenguaje
- Declaración
- JavaScript
translation_of: Web/JavaScript/Reference/Statements/for...in
original_slug: Web/JavaScript/Referencia/Sentencias/for...in
---
<div>{{jsSidebar("Statements")}}</div>
<p>La instrucción {{JSxRef("Sentencias/for...in", "for-in")}} itera sobre todas las {{JSxRef("../Enumerability_and_ownership_of_properties", "propiedades enumerables")}} de un objeto que está codificado por cadenas (ignorando los codificados por {{JSxRef("Objetos_globales/Symbol", "Símbolos")}}, incluidas las propiedades enumerables heredadas.</p>
<div>{{EmbedInteractiveExample("pages/js/statement-forin.html")}}</div>
<p class="hidden">La fuente de este ejemplo interactivo se almacena en un repositorio de GitHub. Si deseas contribuir al proyecto de ejemplos interactivos, clona <a href="https://github.com/mdn/interactive-examples">https://github.com/mdn/interactive-examples</a> y envíanos una solicitud de extracción.</p>
<h2 id="Sintaxis">Sintaxis</h2>
<pre class="syntaxbox notranslate">for (<var>variable</var> in <var>objeto</var>)
instrucción</pre>
<dl>
<dt><code>variable</code></dt>
<dd>Asigna un nombre de propiedad diferente a la <em>variable</em> en cada iteración.</dd>
<dt><code>objeto</code></dt>
<dd>Objeto cuyas propiedades enumerables que no son símbolos se iteran.</dd>
</dl>
<h2 id="Descripción">Descripción</h2>
<p>Un bucle <code>for...in</code> solo itera sobre propiedades enumerables que no son símbolo. Los objetos creados a partir de constructores integrados como <code>Array</code> y <code>Object</code> han heredado propiedades no enumerables de <code>Object.prototype</code> y <code>String.prototype</code>, como el método {{JSxRef("String.indexOf", "indexOf()")}} de {{JSxRef("String")}} o el método {{JSxRef("Object.toString", "toString()")}} de {{JSxRef("Object")}}. El bucle iterará sobre todas las propiedades enumerables del objeto en sí y aquellas que el objeto hereda de su cadena de prototipos (las propiedades de los prototipos más cercanos tienen prioridad sobre las de los prototipos más alejados del objeto en su cadena de prototipos).</p>
<h3 id="Propiedades_deleted_added_o_modified">Propiedades <code>deleted</code>, <code>added</code> o <code>modified</code></h3>
<p>Un bucle <code>for...in</code> itera sobre las propiedades de un objeto en un orden arbitrario (consulta el operador {{JSxRef("Operadores/delete", "delete")}} para obtener más información sobre por qué no puede depender del aparente orden de la iteración, al menos en una configuración entre navegadores).</p>
<p>Si una propiedad se modifica en una iteración y luego se visita en un momento posterior, su valor en el bucle es su valor en ese momento posterior. Una propiedad que se elimina antes de haber sido visitada no se visitará más tarde. Las propiedades agregadas al objeto sobre el que se está produciendo la iteración se pueden visitar u omitir de la iteración.</p>
<p>En general, es mejor no agregar, modificar o eliminar propiedades del objeto durante la iteración, aparte de la propiedad que se está visitando actualmente. No hay garantía de si se visitará una propiedad agregada, si se visitará una propiedad modificada (distinta de la actual) antes o después de que se modifique, o si se visitará una propiedad eliminada antes de eliminarla.</p>
<h3 id="Iteración_en_arreglos_y_for...in">Iteración en arreglos y <code>for</code>...<code>in</code></h3>
<div class="note">
<p><strong>Nota</strong>: <code>for...in</code> no se debe usar para iterar sobre un {{JSxRef("Array")}} donde el orden del índice es importante.</p>
</div>
<p>Los índices del arreglo son solo propiedades enumerables con nombres enteros y, por lo demás, son idénticos a las propiedades generales del objeto. No hay garantía de que <code>for...in</code> devuelva los índices en un orden en particular. La instrucción de bucle <code>for...in</code> devolverá todas las propiedades enumerables, incluidas aquellas con nombres no enteros y aquellas que se heredan.</p>
<p>Debido a que el orden de iteración depende de la implementación, es posible que la iteración sobre un arreglo no visite los elementos en un orden coherente. Por lo tanto, es mejor usar un bucle {{JSxRef("Sentencias/for", "for")}} con un índice numérico (o {{JSxRef("Array.prototype.forEach()")}} o el bucle {{JSxRef("Sentencias/for...of", "for...of")}}) cuando se itera sobre arreglos donde el orden de acceso es importante.</p>
<h3 id="Iterar_solo_sobre_propiedades_directas">Iterar solo sobre propiedades directas</h3>
<p>Si solo deseas considerar las propiedades adjuntas al objeto en sí mismo, y no sus prototipos, usa {{JSxRef("Object.getOwnPropertyNames", "getOwnPropertyNames()")}} o realiza una {{JSxRef("Object.prototype.hasOwnProperty", "hasOwnProperty()")}} verificación ({{jsxref("Object.prototype.propertyIsEnumerable", "propertyIsEnumerable()")}} también se puede utilizar). Alternativamente, si sabes que no habrá ninguna interferencia de código externo, puedes extender los prototipos incorporados con un método de verificación.</p>
<h2 id="¿Por_qué_usar_for...in">¿Por qué usar <code>for</code>...<code>in</code>?</h2>
<p>Dado que <code>for...in</code> está construido para iterar propiedades de objeto, no se recomienda su uso con arreglos y opciones como <code>Array.prototype.forEach()</code> y existe <code>for...of</code>, ¿cuál podría ser el uso de <code>for...in</code>?</p>
<p>Es posible que se utilice de forma más práctica con fines de depuración, ya que es una forma fácil de comprobar las propiedades de un objeto (mediante la salida a la consola o de otro modo). Aunque los arreglos suelen ser más prácticos para almacenar datos, en situaciones en las que se prefiere un par clave-valor para trabajar con datos (con propiedades que actúan como la "clave"), puede haber casos en los que desees comprobar si alguna de esas claves cumple un valor particular.</p>
<h2 id="Ejemplos">Ejemplos</h2>
<h3 id="Utilizar_for...in">Utilizar <code>for</code>...<code>in</code></h3>
<p>El siguiente bucle <code>for...in</code> itera sobre todas las propiedades enumerables que no son símbolos del objeto y registra una cadena de los nombres de propiedad y sus valores.</p>
<pre class="brush: js notranslate">var obj = {a: 1, b: 2, c: 3};
for (const prop in obj) {
console.log(`obj.${prop} = ${obj[prop]}`);
}
// Produce:
// "obj.a = 1"
// "obj.b = 2"
// "obj.c = 3"</pre>
<h3 id="Iterar_propiedades_directas">Iterar propiedades directas</h3>
<p>La siguiente función ilustra el uso de {{JSxRef("Object.prototype.hasOwnProperty", "hasOwnProperty()")}} — las propiedades heredadas no se muestran.</p>
<pre class="brush: js notranslate">var triangle = {a: 1, b: 2, c: 3};
function ColoredTriangle() {
this.color = 'red';
}
ColoredTriangle.prototype = triangle;
var obj = new ColoredTriangle();
for (const prop in obj) {
if (obj.hasOwnProperty(prop)) {
console.log(`obj.${prop} = ${obj[prop]}`);
}
}
// Produce:
// "obj.color = red"
</pre>
<h2 id="Especificaciones">Especificaciones</h2>
<table class="standard-table">
<tbody>
<tr>
<th scope="col">Especificación</th>
</tr>
<tr>
<td>{{SpecName('ESDraft', '#sec-for-in-and-for-of-statements', 'declaración for...in')}}</td>
</tr>
</tbody>
</table>
<h2 id="Compatibilidad_del_navegador">Compatibilidad del navegador</h2>
<div class="hidden">La tabla de compatibilidad de esta página se genera a partir de datos estructurados. Si deseas contribuir con los datos, consulta <a href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> y envíanos una solicitud de extracción.</div>
<p>{{Compat("javascript.statements.for_in")}}</p>
<h3 id="Compatibilidad_expresiones_iniciadoras_en_modo_estricto">Compatibilidad: expresiones iniciadoras en modo estricto</h3>
<p>Antes de Firefox 40, era posible utilizar una expresión iniciadora (<code>i=0</code>) en un bucle <code>for...in</code>:</p>
<pre class="brush: js example-bad notranslate">var obj = {a: 1, b: 2, c: 3};
for (var i = 0 in obj) {
console.log(obj[i]);
}
// 1
// 2
// 3
</pre>
<p>Este comportamiento no estándar ahora se ignora en la versión 40 y posteriores, y presentará un {{JSxRef("SyntaxError")}} ("{{JSxRef("errors/Invalid_for-in_initializer", "iniciador for...in no válido", "las declaraciones de encabezado del bucle for-in posiblemente no tengan iniciadores")}} en {{JSxRef("Strict_mode", "modo estricto")}} ({{bug(748550)}} y {{bug(1164741)}}").</p>
<p>Otros motores como v8 (Chrome), Chakra (IE/Edge) y JSC (WebKit/Safari) están investigando si eliminar también el comportamiento no estándar.</p>
<h2 id="Ve_también">Ve también</h2>
<ul>
<li>{{JSxRef("Sentencias/for...of", "for...of")}} — una declaración similar que itera sobre la propiedad <code>values</code></li>
<li>{{JSxRef("Sentencias/for_each...in", "for each...in")}} — una declaración similar pero obsoleta que itera sobre los valores de las propiedades de un objeto, en lugar de los nombres de las propiedades en sí</li>
<li>{{JSxRef("Sentencias/for", "for")}}</li>
<li>{{JSxRef("../Guide/Iterators_and_Generators", "Expresiones generadoras")}} (usa la sintaxis <code>for...in</code>)</li>
<li>{{JSxRef("../Enumerability_and_ownership_of_properties", "Enumerabilidad y posesión de propiedades")}}</li>
<li>{{JSxRef("Object.getOwnPropertyNames()")}}</li>
<li>{{JSxRef("Object.prototype.hasOwnProperty()")}}</li>
<li>{{JSxRef("Array.prototype.forEach()")}}</li>
</ul>
|