O arguments
objeto em JavaScript é uma verruga estranha - ele atua como uma matriz na maioria das situações, mas na verdade não é um objeto de matriz. Desde que é realmente algo completamente diferente , ele não tem as funções úteis de Array.prototype
como forEach
, sort
, filter
, e map
.
É trivialmente fácil construir uma nova matriz a partir de um objeto de argumentos com um loop for simples. Por exemplo, esta função classifica seus argumentos:
function sortArgs() {
var args = [];
for (var i = 0; i < arguments.length; i++)
args[i] = arguments[i];
return args.sort();
}
No entanto, isso é algo lamentável a ser feito simplesmente para obter acesso às funções extremamente úteis da matriz JavaScript. Existe uma maneira interna de fazer isso usando a biblioteca padrão?
javascript
arrays
sorting
arguments
variadic-functions
Andrew Coleson
fonte
fonte
Respostas:
ES6 usando parâmetros de descanso
Se você puder usar o ES6, poderá usar:
Parâmetros de repouso
Como você pode ler no link
Se você está curioso sobre a
...
sintaxe, ela se chama Operador de propagação e pode ler mais aqui .ES6 usando Array.from ()
Usando Array.from :
Array.from
basta converter objetos do tipo Array ou Iterable em instâncias do Array.ES5
Na verdade, você pode simplesmente usar
Array
aslice
função de s em um objeto de argumentos e ele será convertido em uma matriz JavaScript padrão. Você apenas terá que referenciá-lo manualmente através do protótipo do Array:Por que isso funciona? Bem, aqui está um trecho da própria documentação do ECMAScript 5 :
Portanto,
slice
funciona em qualquer coisa que tenha umalength
propriedade, o quearguments
convenientemente faz.Se
Array.prototype.slice
for demais para você, você pode abreviá-lo um pouco usando literais de matriz:No entanto, tenho a impressão de que a versão anterior é mais explícita, então prefiro. O abuso da notação literal da matriz parece estranho e parece estranho.
fonte
0
? Como não há argumentos que você queira passar, por que você não pode simplesmente usarvar args = Array.prototype.slice.call(arguments);
? [ A página de argumentos do MDC ] ( developer.mozilla.org/en/JavaScript/Reference/… ) sugere o método sem o0
.function sortArgs(...argsToSort) { return argsToSort.sort(); }
de MDN developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...Também vale a pena fazer referência a esta página wiki da biblioteca de promessas do Bluebird, que mostra como gerenciar o
arguments
objeto na matriz, de maneira a otimizar a função no mecanismo JavaScript da V8 :Este método é usado em favor de
var args = [].slice.call(arguments);
. O autor também mostra como uma etapa de construção pode ajudar a reduzir a verbosidade.fonte
Alguns métodos de matriz são feitos intencionalmente para não exigir que o objeto de destino seja uma matriz real. Eles exigem apenas que o destino tenha uma propriedade chamada length e índices (que devem ser zero ou maiores números inteiros).
fonte
Usar:
Array(arg1, arg2, ...)
retorna[arg1, arg2, ...]
Array(str1)
retorna[str1]
Array(num1)
retorna uma matriz que possuinum1
elementosVocê deve verificar o número de argumentos!
Array.slice
versão (mais lenta):Array.push
versão (mais lenta, mais rápida que a fatia):Mover versão (mais lenta, mas o tamanho pequeno é mais rápido):
Array.concat
versão (mais lenta):fonte
Se você estiver usando jQuery, a seguir, é muito mais fácil lembrar na minha opinião:
fonte
No ECMAScript 6, não há necessidade de usar hacks feios como
Array.prototype.slice()
. Você pode usar a sintaxe de propagação (...
) .Pode parecer estranho, mas é bastante simples. Ele apenas extrai
arguments
os elementos e os coloca de volta na matriz. Se você ainda não entende, veja estes exemplos:Observe que ele não funciona em alguns navegadores mais antigos, como o IE 11; portanto, se você deseja oferecer suporte a esses navegadores, use o Babel .
fonte
Aqui está uma referência de vários métodos para converter argumentos em array.
Quanto a mim, a melhor solução para uma pequena quantidade de argumentos é:
Para outros casos:
fonte
sortArgs
é 6 vezes mais rápido no Firefox, mas duas vezes mais lento no Chrome mais recente, em comparação com oArray.apply
.Eu recomendo usar o operador de propagação ECMAScript 6 , que vinculará os parâmetros finais a uma matriz. Com esta solução, você não precisa tocar no
arguments
objeto e seu código será simplificado. A desvantagem desta solução é que ela não funciona na maioria dos navegadores; portanto, você precisará usar um compilador JS como o Babel. Sob o capô, Babel se transformaarguments
em uma matriz com um loop for.Se você não pode usar o ECMAScript 6, recomendo examinar algumas das outras respostas, como @ Jonathan Fingland
fonte
Lodash:
em ação:
produz:
fonte
_.toArray
?_.toArray
é mais apropriado.Use
Array.from()
, que pega um objeto do tipo matriz (comoarguments
) como argumento e o converte em matriz:Observe que ele não funciona em alguns navegadores mais antigos, como o IE 11; portanto, se você deseja oferecer suporte a esses navegadores, use o Babel .
fonte
fonte
Outra resposta.
Use Magias Negras:
Firefox, Chrome, Node.js, IE11 estão OK.
fonte
__proto__
está obsoleto. Veja os documentos MDN .Tente usar
Object.setPrototypeOf()
Explicação: Ajuste da
prototype
arguments
Array.prototype
Explicação: Pegue cada índice de
arguments
, coloque o item em uma matriz no índice correspondente da matriz.alternativamente poderia usar
Array.prototype.map()
Explicação: Pegue cada índice de
arguments
, coloque o item em uma matriz no índice correspondente da matriz.for..of
cicloou
Object.create()
Explicação: Crie um objeto, defina propriedades do objeto para itens em cada índice de
arguments
; conjuntoprototype
de objetos criados paraArray.prototype
fonte
Object.setPrototypeOf
alerta que é uma "operação muito lenta". Por que diabos eu usaria isso de novoArray.prototype.slice.call
?Aqui está uma solução limpa e concisa:
Object.values( )
devolverá os valores de um objeto como uma matriz, e uma vez quearguments
é um objeto, ele essencialmente irá converterarguments
em uma matriz, proporcionando-lhe todas as funções auxiliares de uma matriz, tais comomap
,forEach
,filter
, etc.fonte
Benshmarck 3 métodos:
RESULTADO?
Desfrutar !
fonte
arguments.length == 1?[arguments[0]]:Array.apply(null, arguments);
impedir que a função seja chamada com apenas um argumento inteirodummyFn(3)
e cause resultado[,,]
dummyFn(3)
que é isso? essa função não existe ...fonte
Embora os parâmetros de descanso funcionem bem, se você quiser continuar usando
arguments
por algum motivo, considere[...arguments]
pode ser considerado uma espécie de alternativa aoArray.from(arguments)
, que também funciona perfeitamente bem.Uma alternativa do ES7 é uma compreensão de matriz:
Isso pode ser mais fácil se você quiser processar ou filtrar os argumentos antes da classificação:
fonte
Eu tentei uma técnica simples de destruição
fonte
O objeto Arguments está disponível apenas dentro de um corpo de função. Embora você possa indexar o objeto Arguments como uma matriz, ela não é uma matriz. Ele não possui outras propriedades da matriz além do comprimento.
Embora possa ser indexado como uma matriz, como você pode ver neste exemplo:
No entanto, o objeto Arguments não é uma matriz e não possui outras propriedades além do comprimento.
Você pode converter o objeto de argumentos em uma matriz em que você pode acessar o objeto Arguments.
Existem várias maneiras de acessar o objeto de argumentos dentro de um corpo de função, e incluem:
Array.prototype.slice.call (argumentos)
[] .slice.call (argumentos).
fonte
Você pode criar uma função reutilizável para fazê-lo com qualquer argumento, a mais simples é algo como isto:
A sintaxe de propagação pode ser usada no ES6 e acima ...
Mas se você deseja usar algo compatível com o ES5 e abaixo, pode usar
Array.prototype.slice.call
, para codificar o seguinte:Existem também algumas outras maneiras de fazer isso, por exemplo, usando
Array.from
ou fazendo um loop através dos argumentos e atribuí-los a uma nova matriz ...fonte
Essa é uma pergunta muito antiga, mas acho que tenho uma solução que é um pouco mais fácil de digitar do que as soluções anteriores e não depende de bibliotecas externas:
fonte
Array.apply
não funcionará se você tiver apenas um único argumento inteiro positivo. Isso ocorre porquenew Array(3)
cria um comprimento de matriz de3
. Para ser mais específico, o resultado será[undefined, undefined, undefined]
e não[3]
.