aboutsummaryrefslogtreecommitdiff
path: root/files/es/web/javascript/novedades_en_javascript/1.7/index.html
blob: d783fdb0b054529756df3b4877f541e7d190828c (plain)
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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
---
title: Novedades en JavaScript 1.7
slug: Web/JavaScript/Novedades_en_JavaScript/1.7
tags:
  - Guía_de_JavaScript_1.5
  - JavaScript
  - Todas_las_Categorías
translation_of: Archive/Web/JavaScript/New_in_JavaScript/1.7
---
<p>{{jsSidebar("New_in_JS")}}</p>

<p>JavaScript 1.7 es una actualización del lenguaje que le añade algunas nuevas características, como generadores, iteradores, comprensión de arrays, sentencias <code>let</code> y asignación desestructurada. Evidentemente también incluye todas las características de <a href="es/Novedades_en_JavaScript_1.6">JavaScript 1.6</a>.</p>

<p>El soporte para JavaScript 1.7 estará disponible a partir de <a href="es/Firefox_2">Firefox 2</a> Beta 1, así como en compilaciones actuales.</p>

<p>Los ejemplos de código incluidos en este artículo pueden ser probados en la consola JavaScript. Si quieres aprender a construir o utilizar esta consola, lee <a href="es/Introducci%c3%b3n_al_shell_de_JavaScript">Introducción al shell de JavaScript</a>.</p>

<h2 id="Utilizando_JavaScript_1.7" name="Utilizando_JavaScript_1.7">Utilizando JavaScript 1.7</h2>

<p>Para usar las nuevas caracteristicas de JavaScript 1.7, es necesario especificar explícitamente el uso de JavaScript 1.7. En HTML o XUL, utiliza:</p>

<pre class="eval"> &lt;script type="application/javascript;version=1.7"/&gt;
</pre>

<p>Cuando se utilice el <a href="es/Introducci%c3%b3n_al_shell_de_JavaScript">shell de JavaScript</a>, debes especificar la versión deseada utilizando la función <code>version()</code>:</p>

<pre class="eval"> version(170);
</pre>

<h2 id="Generadores_e_iteradores" name="Generadores_e_iteradores">Generadores e iteradores</h2>

<p>Cuando se desarrolla código que involucra algoritmos iterativos (como iteraciones sobre listas, o cálculos repetitivos sobre el mismo conjunto de datos), con frecuencia hay variables de estado cuyos valores necesitan ser mantenidos durante el proceso. Tradicionalmente se utilizan funciones callback para obtener los valores intermedios de un algoritmo iterativo.</p>

<h3 id="Generadores" name="Generadores">Generadores</h3>

<p>Considera este algoritmo iterativo que obtiene los números de la serie Fibonacci:</p>

<pre>function do_callback(num) {
  document.write(num + "&lt;BR&gt;\n");
}

function fib() {
  var i = 0, j = 1, n = 0;
  while (n &lt; 10) {
    do_callback(i);
    var t = i;
    i = j;
    j += t;
    n++;
  }
}

fib();
</pre>

<p>Este código utiliza rutinas callback para realizar las operaciones en cada paso del algoritmo. En este caso, cada numero Fibonacci es impreso en la consola.</p>

<p>Los generadores e iteradores trabajan juntos para proveer nuevas y mejores formas de hacer esto. Veamos cómo es la rutina de la serie Fibonacci escrita utilizando generadores:</p>

<pre>function fib() {
  var i = 0, j = 1;
  while (true) {
    yield i;
    var t = i;
    i = j;
    j += t;
  }
}

var g = fib();
for (var i = 0; i &lt; 10; i++) {
  document.write(g.next() + "&lt;BR&gt;\n");
}
</pre>

<p>La función que contiene la palabra clave <code>yield</code> es un generador. Cuando es llamada, sus parámetros formales son instanciados a los argumentos actuales, pero su cuerpo no es realmente evaluado, si no que se devuelve un

 <i>generator-iterator</i>
 . Cada llamada al método <code>next()</code> del

 <i>generator-iterator</i>
 realiza otro paso a través de algoritmo iterativo. El valor de cada paso es el valor especificado por la palabra clave <code>yield</code>. Piensa en <code>yield</code> como la versión

 <i>generator-iterator</i>
 de <code>return</code> que delimita la frontera entre cada iteración del algoritmo. Cada vez que se llama a <code>next()</code>, el código del generador continúa a partir de la sentencia que va después de <code>yield</code>.</p>

<p>Se realiza un ciclo en el generator-iterator llamando repetidamente a su método <code>next()</code> hasta que se consiga la condición deseada. Con este ejemplo se pueden obtener tantos números de Fibonacci como se quiera llamando simplemente a <code>g.next()</code> hasta que conseguir la cantidad de números que se quiera.</p>

<h5 id="Resumiendo_un_generador_en_un_punto_espec.C3.ADfico" name="Resumiendo_un_generador_en_un_punto_espec.C3.ADfico">Resumiendo un generador en un punto específico</h5>

<p>Una vez que un generador ha sido iniciado por la invocación de su función <code>next()</code>, puede utilizarse <code>send()</code>, pasando un valor específico que será tratado como el resultado de la última producción. El generador entonces retornará el operando de la subsecuente producción.</p>

<p>No se puede iniciar un generador en un punto arbitrario; deberá comenzarse con <code>next()</code> antes de poder enviarle {{ mediawiki.external('<code>send()</code>') }} un valor específico.</p>

<div class="note"><b>Nótese:</b> Como un punto interesante, invocando <code>send(undefined)</code> es equivalente a invocar <code>next()</code>. Sin embargo, iniciando la aparición de un nuevo generador con cualquier otro valor que no sea indefinido {{ mediawiki.external('undefined') }} cuando invoque a <code>send()</code> resultará como una excepción de error de tipo {{ mediawiki.external('<code>TypeError</code> exception') }}.</div>

<h5 id="Excepciones_en_los_generadores" name="Excepciones_en_los_generadores">Excepciones en los generadores</h5>

<p>Puede forzar a un generador a lanzar una excepción mediante la invoación de su método <code>throw()</code>, pasándole el valor de la excepción que debe ser lanzada. Esta excepción se lanzará desde el conxtexto actual suspendido del generador, así como si el <code>yield</code> que está actualmente suspendido en lugar del sentencia <code>throw
 <i>valor</i>
 </code>.</p>

<p>Si una producción no es encontrada durante el procesamiento de la excepción lanzada, entonces la excepción se propagará ascendentemente hasta la invocación del <code>throw()</code> y subsecuentemente invocará a <code>next()</code> que resulta en el lanzamiento de una <code>StopIteration</code>.</p>

<h5 id="Cerrando_un_generador" name="Cerrando_un_generador">Cerrando un generador</h5>

<p>Los generadores poseen el método <code>close()</code> que forza al generador a cerrarse por sí mismo. Los efectos de cerrar un generador son:</p>

<ol>
 <li>Cualquier cláusula <code>finally</code> activa en la función del generador es ejecutada.</li>
 <li>Si una cláusula <code>finally</code> lanza cualquier excepción distinta a <code>StopIteration</code>, la excepción es propagada hacia el invocador del método <code>close()</code>.</li>
 <li>El generador termina.</li>
</ol>

<h5 id="Ejemplo_de_un_Generador" name="Ejemplo_de_un_Generador">Ejemplo de un Generador</h5>

<p>Este código maneja un generador que se producirá cada 100 lazos.</p>

<pre>var gen = generator();

function driveGenerator() {
	if (gen.next()) {
		window.setTimeout(driveGenerator, 0);
	} else {
		gen.close();
	}
}

function generator() {
	while (i &lt; something) {
		/** stuff **/

		++i;
		/** 100 loops per yield **/
		if ((i % 100) == 0) {
			yield true;
		}
	}

	yield false;
}
</pre>

<h3 id="Iteradores" name="Iteradores">Iteradores</h3>

<p>Un
 <i>iterador</i>
 es un objeto especial que te permite iterar datos.</p>

<p>En el uso cotidiano, los objetos iteradores son
 <i>invisibles</i>
 (no se necesita trabajar con ellos explícitamente) y son usados en <a href="es/Gu%c3%ada_JavaScript_1.5/Sentencias_de_manipulaci%c3%b3n_de_objetos">sentencias <code>for...in</code> y <code>for each...in</code></a> para recorrer de forma natural las claves y/o los valores de los objetos.</p>

<pre>var objectWithIterator = getObjectSomehow();

for (var i in objectWithIterator)
{
  document.write(objectWithIterator[i] + "&lt;BR&gt;\n");
}
</pre>

<p>Si se está implementando un objeto iterador personalizado o se necesita manipular directamente un iterador, será preciso conocer antes el método <code>next()</code>, la excepción <code>StopIteration</code> y la propiedad <code>__iterator__</code>.</p>

<p><span class="comment">traduzco getter como la función get</span> Se puede crear un iterador para un objeto llamando a <code>Iterator(
 <i>objectname</i>
 )</code>. El iterador para cierto objeto se conoce gracias a la propiedad <code>__iterator__</code> de dicho objeto, la cual implementa predeterminadamente la iteración de acuerdo al modelo convencional de <code>for..in</code> y <code>for each...in</code>. Si se desea utilizar un iterador personalizado, se debería sobreescribir la función <a href="es/Gu%c3%ada_JavaScript_1.5/Crear_nuevos_objetos/Definiendo_las_funciones_get_y_set">get</a> para que <code>__iterator__</code> devuelva una instancia del susodicho iterador. Para obtener el iterador de un objeto en un script se debería de usar <code>Iterator(
 <i>obj</i>
 )</code> en lugar de acceder directamente a la propiedad <code>__iterator__</code>.</p>

<p>Una vez se tiene el iterador, se puede buscar fácilmente el siguiente elemento en el objeto llamando su método <code>next()</code>. Cuando no hay más datos se lanza la excepción <code>StopIteration</code>.</p>

<p>A continuación se muestra un ejemplo simple de manipulación directa de iteradores:</p>

<pre>var obj = {name:"Jack Bauer", username:"JackB", id:12345, agency:"CTU", region:"Los Angeles"};

var it = Iterator(obj);

try {
  while (true) {
    document.write(it.next() + "&lt;BR&gt;\n");
  }
} catch (err if err instanceof StopIteration) {
  document.write("End of record.&lt;BR&gt;\n");
} catch (err) {
  document.write("Unknown error: " + err.description + "&lt;BR&gt;\n");
}
</pre>

<p>La salida de este programa tendrá este aspecto:</p>

<pre>name,Jack Bauer
username,JackB
id,12345
agency,CTU
region,Los Angeles
End of record.
</pre>

<p>Opcionalmente se puede especificar un segundo parámetro durante la creación del iterador, el cual es un valor booleano que indica si sólo se quieren obtener las claves cada vez que se llama al método <code>next()</code> o no. Cambiando <code>var it = Iterator(obj);</code> por <code>var it = Iterator(obj, true);</code> en el ejemplo anterior se obtendría la siguiente salida:</p>

<pre>name
username
id
agency
region
End of record.
</pre>

<p>En ambos casos, el orden final en el que los datos son devueltos puede variar dependiendo de la implementación por lo que <b>no se garantiza el orden de los datos</b>.</p>

<p>Los iteradores son un método útil de recorrer los datos de los objetos, incluyendo objetos que pueden contener datos inesperados. Esto puede ser especialmente útil si se necesitan recuperar datos para los que la aplicación no está preparada.</p>

<h2 id="Comprensi.C3.B3n_de_arrays" name="Comprensi.C3.B3n_de_arrays">Comprensión de arrays</h2>

<p>La comprensión de arrays es una forma de utilizar generadores para realizar de manera apropiada potentes inicializaciones de arrays. Por ejemplo:</p>

<pre class="eval">function range(begin, end) {
  for (let i = begin; i &lt; end; ++i) {
    yield i;
  }
}
</pre>

<p><code>range()</code> es un generador que devuelve todos los valores entre &lt;tt&gt;begin&lt;/tt&gt; y &lt;tt&gt;end&lt;/tt&gt;. Una vez definido eso, se puede utilizar así:</p>

<pre class="eval">var diez_cuadrados = [i * i for (i in range(0, 10))];
</pre>

<p>Esto pre-inicializa un nuevo array, <var>diez_cuadrados</var>, para que contenga los cuadrados de los valores del rango <code>0..9</code>.</p>

<p>Se puede usar cualquier sentencia condicional al inicializar un array. Si lo que se quiere es inicializar un array para que contenta los números pares entre 0 y 20, se puede usar este código.</p>

<pre class="eval">var pares = [i for (i in range(0, 21)) if (i % 2 == 0)];
</pre>

<p>Antes de JavaScript 1.7, lo anterior debería haber sido codificado así:</p>

<pre>var evens = [];
for (var i=0; i &lt;= 20; i++) {
  if (i % 2 == 0)
    evens.push(i);
}
</pre>

<p>La comprensión de arrays no sólo es mucho más compacta sino que de hecho es mucho más fácil de leer una vez que nos hemos familiarizado con el concepto.</p>

<h4 id="Reglas_de_.C3.A1mbito" name="Reglas_de_.C3.A1mbito">Reglas de ámbito</h4>

<p>La comprensión de arrays utiliza un bloque implícito en el cual se ubica. Dicho bloque contiene todo el contenido que se halla dentro de los corchetes, además del las declaraciones <code>let</code> implícitas.</p>

<p><span class="comment">''Add details.''</span></p>

<h2 id=".C3.81mbito_de_un_bloque_con_let" name=".C3.81mbito_de_un_bloque_con_let">Ámbito de un bloque con <code>let</code></h2>

<p>Existen varias formas en las que <code>let</code> puede ser usado para manejar el ámbito de un bloque de datos y funciones:</p>

<ul>
 <li>La <b>sentencia <code>let</code></b> proporciona un método de asociar valores con variables, constantes y funciones en el ámbito del bloque, sin afectar a los de las variables que tengan el mismo nombre fuera del bloque.</li>
 <li>La <b>expresión <code>let</code></b> permite establecer variables cuyo ámbito está comprendido en una única expresión.</li>
 <li>La <b>definición <code>let</code></b> define variables, constantes y funciones cuyo ámbito queda restringido al bloque en el que se han definido. Esta sintaxis es muy parecida a la usada para <code>var</code>.</li>
 <li>Además se puede utilizar <code>let</code> para establecer variables que existan sólo dentro del contexto de un bucle <code>for</code>.</li>
</ul>

<p> </p>

<h3 id="El_sentencia_let" name="El_sentencia_let">El sentencia <code>let</code></h3>

<p>La sentencia <code>let</code> proporciona un ámbito local para variables, constantes y funciones. Funciona reservando cero o más variables en el ámbito léxico de un único bloque de código. La validez de la sentencia <code>let</code> finaliza cuando termina el bloque.</p>

<p>Por ejemplo:</p>

<pre>var x = 5;
var y = 0;

let (x = x+10, y = 12) {
  document.write(x+y + "&lt;BR&gt;\n");
}

document.write(x+y + "&lt;BR&gt;\n");
</pre>

<p>tendrá como salida:</p>

<pre>27
5
</pre>

<p>Las reglas para el bloque de código son las mismas que para cualquier otro bloque de código de JavaScript. Puede tener sus propias variables establecidas usando declaraciones <code>let</code>.</p>

<div class="note"><b>Nota:</b> Cuando se use la sintaxis de las sentencia <code>let</code>, será necesario incluir los paréntesis. El no incluirlos provocará un error de sintaxis.</div>

<h4 id="Reglas_de_.C3.A1mbito_2" name="Reglas_de_.C3.A1mbito_2">Reglas de ámbito</h4>

<p>El ámbito de las variables definidas usando <code>let</code> es el del mismo bloque de <code>let</code>, además de cualquier bloque interno contenido dentro de él, a menos que esos bloques definan variables con el mismo nombre.</p>

<h3 id="Expresiones_let" name="Expresiones_let">Expresiones <code>let</code></h3>

<p>Se puede usar <code>let</code> para establecer variables cuyo ámbito comprende sólo una única expresión:</p>

<pre>var x = 5;
var y = 0;
document.write( let(x = x + 10, y = 12) x+y  + "&lt;BR&gt;\n");
document.write(x+y + "&lt;BR&gt;\n");
</pre>

<p>La salida da como resultado:</p>

<pre>27
5
</pre>

<p>En este caso, el ámbito de las variables <var>x</var> = <code>x+10</code> e <var>y</var> = <code>12</code> es utilizado solamente en la expresión <code>x+y</code></p>

<h4 id="Reglas_de_.C3.A1mbito_3" name="Reglas_de_.C3.A1mbito_3">Reglas de ámbito</h4>

<p>Dada la expresión <code>let</code></p>

<pre class="eval">let (<var>decls</var>) <var>expr</var>
</pre>

<p>existe un bloque creado implícitamente que comprende el trozo <var>expr</var>.</p>

<h3 id="Definiciones_let" name="Definiciones_let">Definiciones <code>let</code></h3>

<p>La palabra clave <code>let</code> puede además ser usada para definir variables, constantes y funciones dentro de un bloque.</p>

<pre> ** Este código no funciona en FF 2.0 b1. **
if (x &gt; y)
{
   let const k = 37;
   let gamma : int = 12.7 + k;
   let i = 10;
   let function f(n) { return (n/3)+k; }
   return f(gamma) + f(i);
}
</pre>

<h4 id="Reglas_de_.C3.A1mbito_4" name="Reglas_de_.C3.A1mbito_4">Reglas de ámbito</h4>

<p>Las variables, funciones y constantes declaradas usando <code>let</code>, <code>let function</code> y <code>let const</code> tienen como ámbito el bloque en el que están definidas, además de cualquier sub-bloque en el que no sean redefinidas. De este modo, <code>let</code> funciona como <code>var</code>.</p>

<p>En los programas y clases, <code>let</code> no crea propiedades en los objetos y clases globales como hace <code>var</code>. En vez de eso, crea propiedades en un bloque implícito creado para la evaluación de sentencias en dichos contextos. Esto significa esencialmente que <code>let</code> no sobreescribirá las variables previamente definidas usando <code>var</code>. Por ejemplo:</p>

<pre>** No funciona en FF 2.0 b1. Devuelve "42", no "global".
var x = 'global';
let x = 42;
document.write(this.x + "&lt;BR&gt;\n");
</pre>

<p>La salida mostrada por este código será "global", no "42".</p>

<p>Un
 <i>bloque implícito</i>
 es aquel que no está comprendido entre llaves; es creado implícitamente por el motor de JavaScript.</p>

<p>En las funciones, una sentencia <code>let</code> ejecutada dentro de <code>eval()</code> no crea propiedades en el objeto variable <span class="comment">Esto hay que traducirlo: (activation object or innermost binding rib)</span> como sí hace <code>var</code>. En vez de eso, lo hace en un bloque creado implícitamente para la evaluación de las sentencias del programa. Esto es consecuencia de la forma de trabajar de <code>eval()</code> unido a la anterior regla.</p>

<p>En otras palabras, cuando se usa <code>eval()</code> para ejecutar código, dicho código es es tratado como un programa independiente el cual tiene su propio bloque implícito alrededor de su código.</p>

<h3 id=".C3.81mbito_de_variables_con_let_en_bucles_for" name=".C3.81mbito_de_variables_con_let_en_bucles_for">Ámbito de variables con <code>let</code> en bucles <code>for</code></h3>

<p>Se puede usar la palabra reservada <code>let</code> para declarar variables localmente en el ámbito de un bucle <code>for</code>, al igual que con <code>var</code>.</p>

<pre>** Add obj **
   var i=0;
   for ( let i=i ; i &lt; 10 ; i++ )
     document.write(i + "&lt;BR&gt;\n");

   for ( let [name,value] in obj )
     document.write("Name: " + name + ", Value: " + value + "&lt;BR&gt;\n");
</pre>

<h4 id="Reglas_de_.C3.A1mbito_5" name="Reglas_de_.C3.A1mbito_5">Reglas de ámbito</h4>

<pre class="eval">for (let <var>expr1</var>; <var>expr2</var>; <var>expr3</var>) <var>sentencia</var>
</pre>

<p>En este ejemplo, <var>expr2</var>, <var>expr3</var> y <var>sentencia</var> están delimitadas por un bloque implícito que contiene a las variables locales al bloque declaradas por <code>let <var>expr1</var></code>. Esto se demuestra en el primer bucle del ejemplo.</p>

<pre class="eval">for (<var>expr1</var> in <var>expr2</var>) <var>sentencia</var>
</pre>

<p>En este caso, existe un bloque implícito que contiene a <var>sentencia</var>. Esto es mostrado en el segundo bucle del ejemplo.</p>

<h2 id="Asignaci.C3.B3n_desestructurada" name="Asignaci.C3.B3n_desestructurada">Asignación desestructurada</h2>

<p>La asignación desestructurada hace posible extraer datos desde arrays u objetos utilizando una sintaxis que refleja la construcción de arrays y objetos literales.</p>

<p>Las expresiones de objetos y arrays literales proporcionan una forma fácil de crear paquetes de datos ad hoc. Una vez creados estos paquetes de datos, pueden ser usados como se quiera. Se pueden devolver incluso desde funciones.</p>

<p>Una peculiaridad especialmente útil que se puede hacer con la asignación desestructurada es leer una estructura completa desde una única sentencia aunque hay un número de cosas interesantes que se pueden hacer con ella, como muestra la siguiente sección repleta de ejemplos.</p>

<p>Esta capacidad es similar a las características que presentan lenguajes tales como Perl o Python.</p>

<h3 id="Ejemplos" name="Ejemplos">Ejemplos</h3>

<p>La asignación desestructurada se explica mejor con ejemplos por lo que aquí se muestran un par de ellos con fines didáctico.</p>

<div class="note"><b>Nota:</b> Si tienes ejemplos más interesantes con formas de utilizar la asignación desestructurada, por favor, anímate a añadirlos a esta sección.</div>

<h4 id="Intercambiando_valores" name="Intercambiando_valores">Intercambiando valores</h4>

<p>Se puede usar la asignación desestructurada para, por ejemplo, intercambiar valores:</p>

<pre>var a = 1;
var b = 3;

[a, b] = [b, a];
</pre>

<p>Tras ejecutar este código, <var>b</var> valdrá 1 y <var>a</var> valdrá 3.</p>

<p>O para rotar valores: (formato de código pobre)</p>

<pre>&lt;body bgcolor = "black"&gt;

&lt;script type="application/javascript;version=1.7"/&gt;

var a = 'o';
var b = "&lt;font color = 'green'&gt;o&lt;/font&gt;";
var c = 'o';
var d = 'o';
var e = 'o';
var f = "&lt;font color = 'blue'&gt;o&lt;/font&gt;";
var g = 'o';
var h = 'o';

for (lp=0;lp&lt;40;lp++)
	{[a, b, c, d, e, f, g, h] = [b, c, d, e, f, g, h, a];
	 document.write(a+''+b+''+c+''+d+''+e+''+f+''+g+''+h+''+"&lt;br /&gt;");}
&lt;/script&gt;
</pre>

<p>Después de ejecutar este código, se mostrará un espectáculo de colores gracias a la rotación de las variables.</p>

<h4 id="Devolviendo_m.C3.BAltiples_valores" name="Devolviendo_m.C3.BAltiples_valores">Devolviendo múltiples valores</h4>

<p>Gracias a la asignación desestructurada, las funciones pueden devolver múltiples valores. Dado que las funciones siempre han podido devolver funciones, ésto proporciona una vuelta de tuerca a la flexibilidad.</p>

<pre>function f() {
  return [1, 2];
}
</pre>

<p>Como se puede observar, los resultados se devuelven usando una notación parecida a la utilizada con los arrays, con los valores que se quieren devolver encerrados entre corchetes. Así, se puede devolver un número cualquiera de resultados. En el siguiente ejemplo, <code>f()</code> devuelve el valor <code>{{ mediawiki.external('1, 2') }}</code>.</p>

<pre>var a, b;
[a, b] = f();
document.write ("A es " + a + " B es " + b + "&lt;BR&gt;\n");
</pre>

<p>El comando <code>{{ mediawiki.external('a, b') }} = f()</code> asigna el resultado de la función a las variables ubicadas por orden entre corchetes: <var>a</var> queda establecido a 1 y <var>b</var> a 2.</p>

<p>También se pueden obtener los valores devueltos como un array:</p>

<pre>var a = f();
document.write ("A es " + a);
</pre>

<p>En este caso, <var>a</var> será un array que contendrá los valores 1 y 2.</p>

<h4 id="Ignorar_ciertos_valores_devueltos" name="Ignorar_ciertos_valores_devueltos">Ignorar ciertos valores devueltos</h4>

<p>Se pueden ignorar algunos valores devueltos en los que no se esté interesado:</p>

<pre>function f() {
  return [1, 2, 3];
}

var [a, , b] = f();
document.write ("A is " + a + " B is " + b + "&lt;BR&gt;\n");
</pre>

<p>Tras ejecutar este código, <var>a</var> valdrá 1 y <var>b</var>, 3. El valor 2 es ignorado.</p>

<h4 id="Iteraci.C3.B3n_sobre_objetos" name="Iteraci.C3.B3n_sobre_objetos">Iteración sobre objetos</h4>

<p>Se puede usar asignación desestructurada para recuperar datos de un objeto.</p>

<pre>var obj = { nombre: "Bob", puntos: 1.5, edad: 35 };

for (let[nombre, valor] in obj) {
  document.write ("Nombre: " + nombre + ", Valor: " + valor + "&lt;BR&gt;\n");
}
</pre>

<p>Este bucle recorre todos los pares clave/valor del objeto <var>obj</var> y muestra sus nombres y valores. En este caso, la salida será algo así:</p>

<pre>Nombre: nombre, Valor: Bob
Nombre: puntos, Valor: 1.5
Nombre: edad, Valor: 35
</pre>

<h4 id="Iteraci.C3.B3n_sobre_valores_en_arrays_de_objetos" name="Iteraci.C3.B3n_sobre_valores_en_arrays_de_objetos">Iteración sobre valores en arrays de objetos</h4>

<p>Se puede iterar un array de objetos, accediendo a los campos que interesen de cada objeto.</p>

<pre>var personas  = [
  {
    nombre: "Mike Smith",
    familia: {
      madre: "Jane Smith",
      padre: "Harry Smith",
      hermana: "Samantha Smith"
    },
    edad: 35
  },
  {
    nombre: "Tom Jones",
    familia: {
      madre: "Norah Jones",
      padre: "Richard Jones",
      hermano: "Howard Jones"
    },
    edad: 25
  }
];

for each (let {nombre: n, familia: { padre: f } } in personas) {
  document.write ("Nombre: " + n + ", Padre: " + f + "&lt;BR&gt;\n");
}
</pre>

<p>Esto copia el valor del campo <var>nombre</var> a <var>n</var> y el del campo <var>familia.padre</var> a <var>f</var> y luego los muestra por pantalla. Esto se hace para cada objeto del array <var>personas</var>. La salida será algo así:</p>

<pre>Nombre: Mike Smith, Padre: Harry Smith
Nombre: Tom Jones, Padre: Richard Jones
</pre>

<p><span class="comment">Categorías</span> <span class="comment">enlaces interwikis</span></p>

<div class="noinclude"> </div>

<p>{{ languages( { "en": "en/New_in_JavaScript_1.7", "fr": "fr/Nouveaut\u00e9s_dans_JavaScript_1.7", "it": "it/Novit\u00e0_in_JavaScript_1.7", "ja": "ja/New_in_JavaScript_1.7", "pl": "pl/Nowo\u015bci_w_JavaScript_1.7", "zh-tw": "zh_tw/JavaScript_1.7_\u65b0\u9bae\u4e8b" } ) }}</p>