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

Foi útil?

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:

  1. Tem membros que nomes são números, então eles são como índices de Array
  2. 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

Mozilla sobre o assunto:

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];
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top