Passagem de parâmetros elegante em Javascript
Suponha a seguinte definição de função em Javascript:
function foo(p1, p2,){
...
}
As seguinte chamadas são válidas: foo(), foo(1), foo(1, 2) e foo(1, 2, 3). No primeiro caso, a função foo será chamada e as variáveis terão todas valor null. No segundo caso, p1 terá valor 1 e p2, null. No segundo caso, p1 e p2 terão valor 1 e 2 respectivamente. No terceiro também, e o valor 3 poderá ser acessado pela variável local arguments (leia o meu post sobre argumentos variáveis em Javascript para entender esta funcionalidade).
Ou seja: uma declaração de função em javascript é extremamente flexível. Uma função sempre pode receber um número variável de parâmetros. A definição de parâmetros formais da função apenas define um nome a priori para estes valores.
Este flexibilidade toda seria ótima se Javascript, assim como Python, permitisse a identificação dos parâmetros na chamada da função. Por exemplo, se eu quisesse chamar foo apenas com o valor da variável p2, eu poderia chamar foo(p2=2). Infelizmente isto não funciona: Javascript vai preenchendo as variáveis na ordem em que elas aparecem na definição . Portanto se eu quisesse apenas atribuir um valor a p2, teria que chamar foo(null, 2). Além disso, a linguagem não permite definir valores defaut para os parâmetros.
Uma forma elegante de contornar esta limitação da linguagem, utilizando um recurso extremamente útil implementado nativamente, e de quebra permitir que as variáveis sejam identificadas na chamada ( o que facilita muito a leitura e manutenção do código, quando chamamos funções que aceitam muitos parâmetros) é criar funções que recebam sempre apenas um argumento: um dicionário.
Eis uma nova implementação de foo que recebe os mesmo 3 parâmetros, utilizando um dicionário, e que de quebra define valores default para cada um deles caso o usuário não defina:
function foo(params){
var p1 = params.p1 || 1;
var p2 = params.p2 || 2;
var p3 = params.p3 || "string"
}
Neste caso, caso eu queira chamar foo apenas com os valores de p2 e p3, eu executo foo({p2:2, p3: 3}). Simples assim.
A construção var p1 = params.p1 || 1 utiliza propriedades das expressões booleana para determinar o valor. Em javascript, uma função OR retorna o valor do primeiro elemento que for avaliado como verdadeiro, ou o valor do último elemento avaliado caso todos sejam falsos. Os valores null, 0, false, undefined e “” (string vazia) retornam falso. Caso o parâmetro não seja definido pelo usuário na chamada da função, params.<nome do atributo> retorna null, e portanto o segundo valor da expressão booleana é atribuido à variável.
Quer aprender mais dicas avançadas de Javascript? Funções com argumentos variáveis em Javascript, Captura de teclas em Javascript - Parte 1, Captura de teclas em Javascript - Parte 2 e Concatenação eficiente de Strings em Javascript e AJAX em 20 minutos.

Bruno,
Isso Java não faz!
Pelo menos eu acho que não, hehe…
Um abraço,
Leonardo Garcia
Como assim?!? Receber um
java.util.Mapcomo único argumento de um método?Eu achei ainda que o Miguel iria mostrar a sintaxe para enviar named arguments usando a definição inline de um objeto como em:
foo( { argX : 'afy', argY : 36 } );. Ai sim “Java não tem”Bruno,
usar um Map em Java é possível, mas é um pouquinho mais verboso do que em Javascript. E em java vc não pode usar expressões booleanas para atribuir valores à variáveis, nem usar 0, string vazia ou null como valor de false.
E finalmente, não entendi uma coisa:
“Eu achei ainda que o Miguel iria mostrar a sintaxe para enviar named arguments usando a definição inline de um objeto como em: foo( { argX : ‘afy’, argY : 36 } );”
Eu não mostrei? Releia direito o texto.
Miguel,
O meu “Como assim?” foi para a resposta do Leonardo. Tomei por base o seu exemplo:
function foo(params){
var p1 = params.p1 || 1;
var p2 = params.p2 || 2;
var p3 = params.p3 || “string”
}
Se fosse só passar o mapa, como eu achei que era só o que estava sendo comentado, ai não teria diferença de java mesmo.
Mas realmente você citou a sintaxe que eu mencionei na minha primeira resposta, eh que ela estava em menor destaque “inline” em uma frase logo abaixo, realmente devo ter lido muito rapidamente e passado por cima.
Só achei estranho você não ter dado tanta ênfase visual a esta sintaxe pois é ela que faz toda a diferença para o envido de paramentros ser mais “nomeado” em JS. Acho que esperava ela com mais destaque no texto, por isto mesmo, não vendo ela, postei como sugestão. Sei lá, tentei ajudar o artigo, mas não deu muito certo, pelo visto os ânimos estavam inflamados, novamente.