recursivamente a concatenação de um javascript argumentos de funções
-
20-08-2019 - |
Pergunta
Eu vim através de um javascript quebra-cabeça se perguntando:Escrever uma única linha pedaço de código JavaScript que concatene todas as strings passadas para uma função:
function concatenate(/*any number of strings*/) {
var string = /*your one line here*/
return string;
}
@ meebo
Vendo que os argumentos da função são representadas como um objeto indexado TALVEZ uma matriz, eu pensei que pode ser feito de uma forma recursiva.No entanto a minha implementação recursiva é que ocorra um erro.--"conc.argumentos.mudança não é uma função" --
function conc(){
if (conc.arguments.length === 0)
return "";
else
return conc.arguments.shift() + conc(conc.arguments);
}
parece que conc.argumentos não é uma matriz, mas pode ser acessado por um número de índice e tem um comprimento de propriedade???confuso -- por favor, compartilhe opiniões e outras implementações recursiva.
Obrigado
Solução
arguments
é dito ser uma Matriz como objeto.Como você já viu, você pode acessar seus elementos pelo índice, mas você não tem tudo a Matriz métodos à sua disposição.Outros exemplos de Matriz como objetos de HTML são coleções devolvidos por getElementsByTagName() ou getElementsByClassName().jQuery, se você já usou, é também uma Matriz como objeto.Depois de consultar alguns objetos DOM, inspecionamos o objeto jQuery com o Firebug no DOM guia e você verá o que quero dizer.
Aqui está a minha solução para o Meebo problema:
function conc(){
if (arguments.length === 0)
return "";
else
return Array.prototype.slice.call(arguments).join(" ");
}
alert(conc("a", "b", "c"));
Array.prototype.slice.call(arguments)
é um bom truque para transformar a nossa arguments
em um verdadeiro objeto de Matriz.No Firefox Array.slice.call(arguments)
seria o suficiente, mas ele não vai funcionar no IE6 (pelo menos), de modo que a versão anterior é o que é normalmente utilizado.Além disso, esse truque não funciona para a coleção retornada por DOM métodos da API no IE6 (pelo menos);ele irá lançar um Erro.Pelo caminho, em vez de call
pode-se usar apply
.
Uma pequena explicação sobre a Matriz-como objetos.Em JavaScript você pode usar praticamente qualquer coisa para nomear os membros de um objeto, e os números não são uma exceção.Assim, você pode construir um objeto que se parece com isto, o que é perfeitamente válido JavaScript:
var Foo = {
bar : function() {
alert('I am bar');
},
0 : function() {
alert('I am 1');
},
length : 1
}
Acima objeto é uma Matriz como objeto por duas razões:
- Tem membros que nomes são números, então eles são como índices de Array
- Ele tem uma
length
propriedade, sem o qual você não pode transformar o objeto em uma verdadeira Matriz com a construção:Array.prototype.slice.call(Foo);
Os argumentos objecto de um objeto de Função é muito parecido com o objeto Foo, só que ele tem o seu propósito especial.
Outras dicas
Os argumentos de objeto não é uma matriz.Ele é semelhante a uma matriz, mas não tem qualquer matriz propriedades, exceto de comprimento.Por exemplo, ele não tem o método pop.No entanto, ele pode ser convertido para um real matriz:
var args = Array.prototype.slice.call(arguments);
Portanto, a solução para o seu problema é bastante simples:
var string = Array.prototype.slice.call(arguments).join("");
BTW:Ele ainda afirma:
Os argumentos de objeto é um local variável disponível em todos os funções;argumentos como uma propriedade de A função não pode mais ser usado.
Você só deve usar arguments
em vez de func.arguments
Isso funciona:
function concatenate(){
return [].join.call(arguments, "");
}
alert(concatenate("one", "two", "three"));
A lista de argumentos não é genuína matriz.Eu acho que você pode pedir emprestado a matriz de métodos e usá-los em argumentos com "call" ou "aplicar".
Você poderia fazer isso:
function concatenate() {
if (arguments.length > 1) {
return arguments[0] + concatenate.apply(this, Array.prototype.splice.call(arguments, 1));
}
return arguments[0];
}