Desestruturação atribuição em JavaScript
-
03-07-2019 - |
Pergunta
Como pode ser visto na changlog Mozilla para JavaScript 1.7 eles adicionaram atribuição desestruturação. Infelizmente eu não gosto muito da sintaxe (por que escrever um e B duas vezes?):
var a, b;
[a, b] = f();
Algo como isso teria sido muito melhor:
var [a, b] = f();
Isso ainda seria compatível com versões anteriores. Python-like desestruturação não seria compatível com versões anteriores.
De qualquer forma a melhor solução para JavaScript 1.5 que eu tenho sido capaz de chegar a é:
function assign(array, map) {
var o = Object();
var i = 0;
$.each(map, function(e, _) {
o[e] = array[i++];
});
return o;
}
Que funciona assim:
var array = [1,2];
var _ = assign[array, { var1: null, var2: null });
_.var1; // prints 1
_.var2; // prints 2
Mas este realmente é uma porcaria porque _ não tem nenhum significado. É apenas uma concha vazia para armazenar os nomes. Mas, infelizmente, ela é necessária porque o JavaScript não tem ponteiros. No lado positivo você pode atribuir valores padrão no caso os valores não são correspondidos. Note também que esta solução não tentar cortar a matriz. Então você não pode fazer algo como {first: 0, rest: 0}
. Mas isso pode ser feito facilmente, se alguém quisesse que o comportamento.
O que é uma solução melhor?
Solução
Primeiro, var [a, b] = f()
funciona muito bem em JavaScript 1.7 - experimentá-lo
Em segundo lugar, você pode suavizar a sintaxe de uso ligeiramente usando with()
:
var array = [1,2];
with (assign(array, { var1: null, var2: null }))
{
var1; // == 1
var2; // == 2
}
É claro, isso não vai permitir que você modifique os valores das variáveis ??existentes, de modo que IMHO é muito menos útil do que o recurso de JavaScript 1.7. No código que estou escrevendo agora , eu apenas objetos retornar diretamente e fazer referência a seus membros -. Vou esperar para os 1,7 características para se tornar mais amplamente disponível
Outras dicas
Você não precisa do manequim "_" variável. Você pode criar diretamente variáveis ??"globais" usando o escopo janela objeto:
window["foo"] = "bar";
alert(foo); // Gives "bar"
Aqui estão mais alguns pontos:
- Eu não chamaria essa função "Atribuir" porque isso é muito genérico um termo.
- Para mais parecida com JS 1.7 sintaxe, eu faria a função de tomar o destino como o primeiro argumento ea fonte como a segundo argumento.
- Usando um literal objeto para passar as variáveis ??de destino é legal, mas pode ser confundido com JS 1,7 desestruturação onde o destino é realmente um objeto e não um array. Eu prefiro apenas usando uma lista delimitada por vírgula de nomes das variáveis ??como uma string.
Aqui está o que eu vim com:
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
Aqui está o que eu fiz no PHPstorm 10:
Arquivo -> Configurações -> Línguas & Frameworks -> ...
... Versão definir a linguagem Javascript para, por exemplo, JavaScript 1.8.5 ...
-.> Clique em Aplicar
Em JavaScript padrão que se acostumar com todos os tipos de feiúra, e emulando atribuição desestruturação usando uma variável intermediária não é tão ruim:
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 );
No entanto, penso o seguinte padrão é mais idomatic:
function divMod2(a, b, callback) {
callback(Math.floor(a / b), a % b);
}
divMod2(11, 3, function(div, mod) {
alert("(2) div=" + div + ", mod=" + mod );
});
Note, que, em vez de retornar os dois resultados como uma matriz, que passá-los como argumentos para uma função de retorno de chamada.
(Ver código em execução em http://jsfiddle.net/vVQE3/ )