Pergunta

O objeto arguments em JavaScript é um estranho verruga-age apenas como um array na maioria das situações, mas não é realmente um objeto array. Desde que é realmente algo completamente diferente , ele doesn 't têm as funções úteis a partir Array.prototype como forEach, sort, filter e map.

É tão fácil de construir uma nova matriz de um objeto argumentos com um loop for simples. Por exemplo, esta função ordena seus argumentos:

function sortArgs() {
    var args = [];
    for (var i = 0; i < arguments.length; i++)
        args[i] = arguments[i];
    return args.sort();
}

No entanto, isso é uma coisa bastante lamentável ter que fazer simplesmente para obter acesso às funções extremamente úteis de matrizes de JavaScript. Existe um built-in maneira de fazê-lo usando a biblioteca padrão?

Foi útil?

Solução

ES6 usando parâmetros de descanso

Se você é capaz de usar ES6 você pode usar:

Resto Parâmetros

function sortArgs(...args) {
  return args.sort(function (a, b) { return a - b; });
}

document.body.innerHTML = sortArgs(12, 4, 6, 8).toString();

Como você pode ler no ligação

A sintaxe parâmetro resto nos permite representar um número indefinido de argumentos como uma matriz.

Se você está curioso sobre a sintaxe ..., ele é chamado Espalhe Operador e você pode ler mais aqui .

ES6 usando Array.from ()

Usando Array.from :

function sortArgs() {
  return Array.from(arguments).sort(function (a, b) { return a - b; });
}

document.body.innerHTML = sortArgs(12, 4, 6, 8).toString();

Array.from simplesmente converter array-like ou Iterable objetos em ocorrências de Array.



ES5

Você pode realmente usar apenas Array do slice função em um objeto de argumentos, e ele irá convertê-lo em uma matriz JavaScript padrão. Você só vai ter que fazer referência a ela manualmente através protótipo da matriz:

function sortArgs() {
    var args = Array.prototype.slice.call(arguments);
    return args.sort();
}

Por que isso funciona? Bem, aqui está um trecho da ECMAScript 5 própria documentação :

NOTA : A função slice é intencionalmente genérico; ele não exige que a sua este valor ser um objeto Array. Por isso, pode ser transferida para outros tipos de objetos para uso como um método. Se a função slice pode ser aplicado com sucesso em um objeto de host é dependente de implementação.

Portanto, slice funciona em qualquer coisa que tenha uma propriedade length, que arguments convenientemente faz.


Se Array.prototype.slice é muito de um bocado para você, você pode abreviar-o ligeiramente usando literais de matriz:

var args = [].slice.call(arguments);

No entanto, eu tendem a sentir que a versão anterior é mais explícito, então eu prefiro que em seu lugar. Abusando da matriz notação literal sente hacky e olhares estranhos.

Outras dicas

Também vale a pena referência este Bluebird promete página wiki biblioteca que mostra como para gerenciar o objeto arguments em conjunto de uma forma que faz a função otimizável em motor V8 JavaScript :

function doesntLeakArguments() {
    var args = new Array(arguments.length);
    for(var i = 0; i < args.length; ++i) {
        args[i] = arguments[i];
    }
    return args;
}

Este método é usado em favor de var args = [].slice.call(arguments);. O autor também mostra como uma etapa de compilação pode ajudar a reduzir a verbosidade.

function sortArgs(){ return [].slice.call(arguments).sort() }

// Returns the arguments object itself
function sortArgs(){ return [].sort.call(arguments) }

Alguns métodos de matriz são intencionalmente feitos para não exigir o objecto alvo a ser uma matriz real. Eles só exigem a meta de ter uma propriedade chamada comprimento e índices (que deve ser zero ou maiores números inteiros).

[].sort.call({0:1, 1:0, length:2}) // => ({0:0, 1:1, length:2})

Use:

function sortArguments() {
  return arguments.length === 1 ? [arguments[0]] :
                 Array.apply(null, arguments).sort();
}

Array(arg1, arg2, ...) retornos [arg1, arg2, ...]

Array(str1) retornos [str1]

Array(num1) retorna uma matriz que tem elementos num1

Você deve verificar o número de argumentos!

Versão Array.slice (mais lento):

function sortArguments() {
  return Array.prototype.slice.call(arguments).sort();
}

Versão Array.push (mais lento, mais rápido do que fatia):

function sortArguments() {
  var args = [];
  Array.prototype.push.apply(args, arguments);
  return args.sort();
}

Versão Move (mais lento, mas o tamanho pequeno é mais rápido):

function sortArguments() {
  var args = [];
  for (var i = 0; i < arguments.length; ++i)
    args[i] = arguments[i];
  return args.sort();
}

Versão Array.concat (mais lento):

function sortArguments() {
  return Array.prototype.concat.apply([], arguments).sort();
}

Se você estiver usando jQuery, o seguinte é um bom negócio mais fácil de lembrar na minha opinião:

function sortArgs(){
  return $.makeArray(arguments).sort();
}

Em ECMAScript 6 não há necessidade de usar hacks feios como Array.prototype.slice(). em vez disso você pode usar sintaxe spread (...) .

(function() {
  console.log([...arguments]);
}(1, 2, 3))

Pode parecer estranho, mas é bastante simples. Ele só extrai elementos arguments' e colocá-los de volta para a matriz. Se você ainda não entendo, veja este exemplo:

console.log([1, ...[2, 3], 4]);
console.log([...[1, 2, 3]]);
console.log([...[...[...[1]]]]);

Note que ele não funciona em alguns navegadores mais antigos como o IE 11, então se você quiser para apoiar estes navegadores, você deve usar Babel .

Aqui é referência de vários métodos de conversão argumentos em array.

Quanto a mim, a melhor solução para pequena quantidade de argumentos é:

function sortArgs (){
  var q = [];
  for (var k = 0, l = arguments.length; k < l; k++){
    q[k] = arguments[k];
  }
  return q.sort();
}

Para outros casos:

function sortArgs (){ return Array.apply(null, arguments).sort(); }

Eu recomendo usar ECMAScript 6 operador de propagação , que se ligará de arrasto parâmetros para uma matriz. Com esta solução você não precisa tocar o objeto arguments e seu código será simplificado. A desvantagem desta solução é que ele não funciona na maioria dos navegadores, então em vez disso você terá que usar um compilador JS tais como Babel. Sob o capô Babel transformações arguments para uma matriz com um loop.

function sortArgs(...args) {
  return args.sort();
}

Se você não pode usar um ECMAScript 6, eu recomendo a olhar para algumas das outras respostas tais como @ Jonathan Fingland

function sortArgs() {
    var args = Array.prototype.slice.call(arguments);
    return args.sort();
}

Lodash:

var args = _.toArray(arguments);

em ação:

(function(){ console.log(_.toArray(arguments).splice(1)); })(1, 2, 3)

produz:

[2,3]

Use Array.from() , que leva uma matriz semelhante objecto (tal como arguments) como argumento e converte-a de matriz:

(function() {
  console.log(Array.from(arguments));
}(1, 2, 3));

Note que ele não funciona em alguns navegadores mais antigos como o IE 11, então se você quiser para apoiar estes navegadores, você deve usar Babel .

function sortArg(){
var args = Array.from(arguments); return args.sort();
}

 function sortArg(){
    var args = Array.from(arguments); 
    return args.sort();
    }
 
 console.log(sortArg('a', 'b', 1, 2, '34', 88, 20, '19', 39, 'd', 'z', 'ak', 'bu', 90));

Outra resposta.

Períodos Use Black Magic:

function sortArguments() {
  arguments.__proto__ = Array.prototype;
  return arguments.slice().sort();
}

O Firefox, Chrome, Node.js, IE11 estão OK.

Tente usar Object.setPrototypeOf()

Explicação: Set prototype de arguments para Array.prototype

function toArray() {
  return Object.setPrototypeOf(arguments, Array.prototype)
} 

console.log(toArray("abc", 123, {def:456}, [0,[7,[14]]]))


Explicação: Tome cada índice de arguments, produto lugar em uma matriz no índice de matriz correspondente

.

pode alternativamente usar Array.prototype.map()

function toArray() {
  return [].map.call(arguments, (_,k,a) => a[k])
} 

console.log(toArray("abc", 123, {def:456}, [0,[7,[14]]]))


Explicação: Tome cada índice de arguments, produto lugar em uma matriz no índice de matriz correspondente

.

for..of circuito

function toArray() {
 let arr = []; for (let prop of arguments) arr.push(prop); return arr
} 

console.log(toArray("abc", 123, {def:456}, [0,[7,[14]]]))


ou Object.create()

Explicação: Criar objeto, defina as propriedades do objeto para itens em cada índice de arguments; conjunto prototype de criado objeto para Array.prototype

function toArray() {
  var obj = {};
  for (var prop in arguments) {
    obj[prop] = {
      value: arguments[prop],
      writable: true,
      enumerable: true,
      configurable: true
    }
  } 
  return Object.create(Array.prototype, obj);
}

console.log(toArray("abc", 123, {def: 456}, [0, [7, [14]]]))

Aqui está uma solução limpa e concisa:

function argsToArray() {
  return Object.values(arguments);
}

// example usage
console.log(
  argsToArray(1, 2, 3, 4, 5)
  .map(arg => arg*11)
);

Object.values( ) voltará os valores de um objeto como uma matriz, e desde arguments é um objeto, ele será essencialmente converter arguments em uma matriz, proporcionando-lhe todas as funções auxiliares de uma matriz como map, forEach, filter, etc.

Benshmarck 3 métodos:

function test()
{
  console.log(arguments.length + ' Argument(s)');

  var i = 0;
  var loop = 1000000;
  var t = Date.now();
  while(i < loop)
  {
      Array.prototype.slice.call(arguments, 0); 
      i++;
  }
  console.log(Date.now() - t);


  i = 0,
  t = Date.now();
  while(i < loop)
  {
      Array.apply(null, arguments);
      i++;
  }
  console.log(Date.now() - t);

  i = 0,
  t = Date.now();
  while(i < loop)
  {
      arguments.length == 1 ? [arguments[0]] : Array.apply(null, arguments);
      i++;
  }
  console.log(Date.now() - t);
}

test();
test(42);
test(42, 44);
test(42, 44, 88, 64, 10, 64, 700, 15615156, 4654, 9);
test(42, 'truc', 44, '47', 454, 88, 64, '@ehuehe', 10, 64, 700, 15615156, 4654, 9,97,4,94,56,8,456,156,1,456,867,5,152489,74,5,48479,89,897,894,894,8989,489,489,4,489,488989,498498);

RESULTADO?

0 Argument(s)
256
329
332
1 Argument(s)
307
418
4
2 Argument(s)
375
364
367
10 Argument(s)
962
601
604
40 Argument(s)
3095
1264
1260

Aproveite!

function sortArgs(...args) {
  return args.sort(function (a, b) { return a - b; });
}

document.body.innerHTML = sortArgs(1, 2, 3, 4).toString();

Embora os parâmetros de descanso funcionar bem, se você quiser continuar a usar arguments por alguma razão, considere

function sortArgs() {
  return [...arguments].sort()
}

[...arguments] pode ser considerado uma espécie de alternativa para Array.from(arguments), que também funciona perfeitamente bem.

Um ES7 alternativa é uma compreensão array:

[for (i of arguments) i].sort()

Esta poderia ser mais fácil se você quiser processo ou filtrar os argumentos antes da ordenação:

[for (i of arguments) if (i % 2) Math.log(i)].sort()
 function x(){
   var rest = [...arguments]; console.log(rest);return     
   rest.constructor;
 };
 x(1,2,3)

Eu tentei técnica destructing simples

O objeto Argumentos só está disponível dentro de um corpo função. Embora você possa índice objeto de argumentos como uma matriz, ela não é uma matriz. Ele não tem quaisquer outros do que o comprimento propriedades da matriz.

// function arguments length 5
function properties(a,b,c,d,e){
var function_name= arguments.callee.name
var arguments_length= arguments.length;
var properties_length=  properties.length; 
var function_from= properties.caller.name;
console.log('I am the function name: '+ function_name);
console.log('I am the function length, I am function spacific: '+ properties_length); 
console.log('I am the arguments length, I am context/excution spacific: '+ arguments_length);
console.log('I am being called From: '+  function_from );
}

// arguments 3
function parent(){
properties(1,2,3);
}

//arguments length 3 because execution spacific
parent();

Embora possa ser indexado como um array como você pode ver neste exemplo:

function add(){

var sum=0;

for(var i=0; i< arguments.length;i++){

sum = sum + arguments[i];

}

return sum;

}

console.log(add(1,2,3));

No entanto, o objecto Argumentos não é uma matriz e não tem quaisquer outros do que o comprimento propriedades.

Você pode converter o objeto de argumentos em uma matriz em que ponto você pode acessar o objeto Arguments.

Há muitas maneiras que você pode acessar o objeto argumentos dentro de um corpo da função, e estes incluem:

  1. Você pode chamar o método Array.prototoype.slice.call.

Array.prototype.slice.call (argumentos)

function giveMeArgs(arg1,arg2){

var args = Array.prototype.slice.call(arguments);
return args
}

console.log( giveMeArgs(1,2));

  1. você pode usar a matriz literal

[]. Slice.call (argumentos).

function giveMeArgs(arg1,arg2){

var args = [].slice.call(arguments);

return args;

}

console.log( giveMeArgs(1,2) );

  1. você pode usar Resto ...

function giveMeArgs(...args){

return args;

}

console.log(giveMeArgs(1,2))

  1. você pode usar propagação [...]

function giveMeArgs(){

var args = [...arguments];
return args;

}

console.log(giveMeArgs(1,2));

  1. você pode usar Array.from ()

function giveMeArgs(){

var args = Array.from(arguments);

return args;

}

console.log(giveMeArgs(1,2));

Você pode criar uma função reutilizável para fazê-lo com quaisquer argumentos, o mais simples é algo como isto:

function sortArgs() {
  return [...arguments].sort();
}

sortArgs('ali', 'reza', 1, 2, 'a'); //[1, 2, "a", "ali", "reza"];

sintaxe Propagação pode ser usado em ES6 e acima ...

Mas se você gostaria de usar algo compatível com ES5 e abaixo, você pode usar Array.prototype.slice.call, para que código se parece com isso:

function sortArgs() {
  return Array.prototype.slice.call(arguments).sort();
}

sortArgs('ali', 'reza', 1, 2, 'a'); //[1, 2, "a", "ali", "reza"];

Existem também algumas outras maneiras de fazer isso, por exemplo, usando Array.from ou percorrer os argumentos e atribuí-los a uma nova matriz ...

Esta é uma questão muito antiga, mas eu acho que tenho uma solução que é ligeiramente mais fácil de escrever do que as soluções anteriores e não depende de bibliotecas externas:

function sortArguments() {
  return Array.apply(null, arguments).sort();
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top