2008-10-15 28 views
16

Como se puede ver en el changlog de Mozilla para JavaScript 1.7, han agregado la asignación de desestructuración. Por desgracia yo no soy muy aficionado a la sintaxis (¿por qué escribir y B dos veces?):Asignación de desestructuración en JavaScript

var a, b; 
[a, b] = f(); 

Algo como esto hubiera sido mucho mejor:

var [a, b] = f(); 

Eso seguiría siendo compatible con versiones anteriores . La desestructuración similar a Python no sería retrocompatible.

De todos modos la mejor solución para JavaScript 1.5 que he podido llegar a decir:

function assign(array, map) { 
    var o = Object(); 
    var i = 0; 
    $.each(map, function(e, _) { 
     o[e] = array[i++]; 
    }); 
    return o; 
} 

que funciona como:

var array = [1,2]; 
var _ = assign[array, { var1: null, var2: null }); 
_.var1; // prints 1 
_.var2; // prints 2 

Pero esto realmente apesta porque _ tiene ningún significado. Es solo un caparazón vacío para almacenar los nombres. Pero lamentablemente es necesario porque JavaScript no tiene punteros. En el lado positivo, puede asignar valores predeterminados en caso de que los valores no coincidan. También tenga en cuenta que esta solución no intenta cortar el conjunto. Entonces no puedes hacer algo como {first: 0, rest: 0}. Pero eso podría hacerse fácilmente, si uno quisiera ese comportamiento.

¿Cuál es la mejor solución?

Respuesta

23

En primer lugar, var [a, b] = f() funciona bien en JavaScript 1.7 - probarlo!

En segundo lugar, se puede suavizar la sintaxis de uso ligeramente usando with():

var array = [1,2]; 
with (assign(array, { var1: null, var2: null })) 
{ 
    var1; // == 1 
    var2; // == 2 
} 

Por supuesto, esto no le permitirá modificar los valores de las variables existentes, por lo que en mi humilde opinión es mucho menos útil que la característica de JavaScript 1.7. En el código Estoy escribiendo ahora, simplemente devuelvo objetos directamente y hago referencia a sus miembros. Esperaré a que las características 1.7 estén más ampliamente disponibles.

+0

Gracias! Eso soluciona uno de los inconvenientes :) –

+2

A partir de hoy 'var [a, b] = [1,2];' da como resultado un error de sintaxis en Chrome. – Marcin

+9

@Marcin: JavaScript 1.7 es un [idioma de Mozilla solamente] (http://stackoverflow.com/questions/1330498/what-is-cross-browser-support-for-javascript-1-7s-new-features-specifically -Arkansas). – Shog9

4

No necesita la variable ficticia "_". Se pueden crear directamente las variables "globales" mediante el uso del ámbito objeto de la ventana:

window["foo"] = "bar"; 
alert(foo); // Gives "bar" 

Aquí están algunos puntos más:

  • yo no nombrar esta función "asignar" porque eso es demasiado genérico un término.
  • Para parecerse más a la sintaxis de JS 1.7, haría que la función tome el destino como el primer argumento y la fuente como el segundo argumento .
  • Usar un objeto literal para pasar las variables de destino es genial, pero se puede confundir con la desestructuración de JS 1.7 donde el destino es realmente un objeto y no una matriz. Prefiero simplemente usar una lista delimitada por comas de nombres de variables como una cadena.

Esto es lo que ocurrió:

function destructure(dest, src) { 
    dest = dest.split(","); 

    for (var i = 0; i < src.length; i++) { 
     window[dest[i]] = src[i]; 
    } 
} 

var arr = [42, 66]; 

destructure("var1,var2", arr); 

alert(var1); // Gives 42 
alert(var2); // Gives 66 
+2

Lo único con lo que estoy de acuerdo es en que la desestructuración podría ser un nombre mejor. * origen, el destino es el estilo de Unix. * poblar alcance global no es bueno. No conduce a la capacidad de compilación. * Escribir las variables de salida como una cadena es agotador y más difícil de controlar para el editor. Como escribir SQL. –

+0

@AndersRuneJensen Dado que esto imita una asignación, el destino debería estar casi a la izquierda, de esa manera se parece a '[var1, var2] = arr'. Y 'desestructurar 'es un nombre horrible, sin intención de revelar. Creo que 'assign' es mejor, después de todo, se supone que * es una función de utilidad genérica. Si no, entonces tal vez 'massAssign'? –

0

En JavaScript estándar nos acostumbramos a todo tipo de fealdad, y emulando asignación desestructurada usando una variable intermedia no es tan malo:

function divMod1(a, b) { 
    return [ Math.floor(a/b), a % b ]; 
} 

var _ = divMod1(11, 3); 
var div = _[0]; 
var mod = _[1]; 
alert("(1) div=" + div + ", mod=" + mod); 

Sin embargo creo que el siguiente patrón es más idiomáticas:

function divMod2(a, b, callback) { 
    callback(Math.floor(a/b), a % b); 
} 

divMod2(11, 3, function(div, mod) { 
    alert("(2) div=" + div + ", mod=" + mod); 
}); 

Tenga en cuenta que, en lugar de devolver los dos resultados como una matriz, los pasamos como argumentos a una función de devolución de llamada.

(Ver código que se ejecuta en http://jsfiddle.net/vVQE3/)

1

Esto es lo que hice en PhpStorm 10:

Archivo -> Configuración -> Idiomas & Marcos -> ...

... establecer la versión del lenguaje JavaScript, por ejemplo JavaScript 1.8.5 ...

-> haga clic en Aplicar.

Cuestiones relacionadas