Comment puis-je convertir l'objet "arguments" en un tableau en JavaScript?

L'objet arguments en JavaScript est une verrue étrange-il agit comme un tableau dans la plupart des situations, mais ce n'est pas en fait un objet tableau. Puisque c'est vraiment quelque chose de complètement différent, il n'a pas les fonctions utiles de Array.prototype comme forEach, sort, filter, et map.

, Il est trivialement facile de construire un nouveau tableau à partir d'un objet arguments avec une simple boucle for. Par exemple, cette fonction trie ses arguments:

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

Cependant, il s'agit d'un chose plutôt pitoyable à faire simplement pour avoir accès aux fonctions de tableau JavaScript extrêmement utiles. Existe-t-il un moyen intégré de le faire en utilisant la bibliothèque standard?

390
demandé sur animuson 2009-06-07 04:08:21

20 réponses

ES6 en utilisant les paramètres rest

Si vous êtes capable D'utiliser ES6, vous pouvez utiliser:

Reste Paramètres

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

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

Comme vous pouvez le lire dans le lien

La syntaxe du paramètre rest nous permet de représenter un nombre indéfini d'arguments sous forme de tableau.

Si vous êtes curieux de connaître la syntaxe ..., elle s'appelle Spread Operator {[35] } et vous pouvez en lire plus ici.

ES6 à l'aide du tableau.de ()

À l'Aide de tableau.à partir de:

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

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

Array.from convertissez simplement des objets de type tableau ou itérables en instances de tableau.



ES5

Vous pouvez simplement utiliser Array ' s slice fonction sur un objet arguments, et il le convertira en un tableau JavaScript standard. Vous aurez juste à le référencer manuellement à travers le prototype de Array:

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

Pourquoi cela fonctionne-t-il? Bien, voici un extrait de la documentation ECMAScript 5 elle-même :

NOTE : la fonction slice est intentionnellement générique; elle ne nécessite pas que sa valeur cette valeur soit un objet tableau. Par conséquent, il peut être transféré à d'autres types d'objets pour les utiliser comme une méthode. Si la fonction slice peut être appliquée avec succès à un objet hôte dépend de l'implémentation.

Par conséquent, slice fonctionne sur tout ce qui a une propriété length , ce que arguments fait commodément.


Si Array.prototype.slice est trop bouchée pour vous, vous pouvez l'abréger légèrement en utilisant des littéraux de Tableau:

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

Cependant, j'ai tendance à penser que l'ancienne version est plus explicite, donc je la préférerais à la place. Abuser de la notation littérale du tableau semble hacky et semble étrange.

646
répondu Jonathan Fingland 2018-05-02 12:51:16

Il vaut également la peine de référencer cette page wiki de la bibliothèque Bluebird promises {[5] } qui montre comment gérer l'objet arguments dans un tableau d'une manière qui rend la fonction optimisable sous V8 JavaScript engine :

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

Cette méthode est utilisée en faveur de var args = [].slice.call(arguments);. L'auteur montre également comment une étape de construction peut aider à réduire la verbosité.

36
répondu jbmusso 2015-06-02 18:07:01
function sortArgs(){ return [].slice.call(arguments).sort() }

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

Certaines méthodes de tableau sont intentionnellement conçues pour ne pas exiger que l'objet cible soit un tableau réel. Ils exigent seulement que la cible ait une propriété nommée length et des indices (qui doivent être des entiers nuls ou plus grands).

[].sort.call({0:1, 1:0, length:2}) // => ({0:0, 1:1, length:2})
28
répondu matyr 2014-12-16 04:49:25

Utilisation:

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

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

Array(str1) retourne [str1]

Array(num1) retourne un tableau qui a num1 d'éléments de

, Vous devez vérifier le nombre d'arguments!

Array.slice version (plus lente):

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

Array.push version (plus lente, plus rapide que slice):

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

Déplacer la version (plus lente, mais la petite taille est plus rapide):

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

Array.concat version (la plus lente):

function sortArguments() {
  return Array.prototype.concat.apply([], arguments).sort();
}
12
répondu LightSpeedC Kazuaki Nishizawa 2013-10-27 15:35:27

Si vous utilisez jQuery, ce qui suit est beaucoup plus facile à retenir à mon avis:

function sortArgs(){
  return $.makeArray(arguments).sort();
}
9
répondu brad 2009-06-07 00:19:43

Voici benchmark de plusieurs méthodes convertissant des arguments en tableau.

Quant à moi, la meilleure solution pour une petite quantité d'arguments est:

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

Pour les autres cas:

function sortArgs (){ return Array.apply(null, arguments).sort(); }
4
répondu Gheljenor 2013-07-03 09:05:18

Je recommande D'utiliser ECMAScript 6 spread operator , qui liera les paramètres de fin à un tableau. Avec cette solution, vous n'avez pas besoin de toucher l'objet arguments et votre code sera simplifié. L'inconvénient de cette solution est qu'elle ne fonctionne pas sur la plupart des navigateurs, vous devrez utiliser un compilateur JS comme Babel. Sous le capot Babel transforme arguments en un tableau avec une boucle for.

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

Si vous ne pouvez pas utiliser un ECMAScript 6, je vous recommande de regarder certains parmi les autres réponses telles que @ Jonathan Fingland

function sortArgs() {
    var args = Array.prototype.slice.call(arguments);
    return args.sort();
}
4
répondu jjbskir 2016-01-25 21:51:50

Lodash:

var args = _.toArray(arguments);

En action:

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

Produit:

[2,3]
4
répondu Zane Hooper 2017-03-14 05:55:57

Utilisation Array.from(), qui prend un objet de type tableau (tel que arguments) comme argument et le convertit en tableau:

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

Notez que cela ne fonctionne pas dans certains navigateurs plus anciens comme IE 11, donc si vous voulez prendre en charge ces navigateurs, vous devez utiliser Babel.

4
répondu Michał Perłakowski 2017-08-28 15:51:15
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));
3
répondu Abk 2017-02-17 21:08:47

Dans ECMAScript 6, il n'est pas nécessaire d'utiliser des hacks moches comme Array.prototype.slice(). Vous pouvez utiliser à la place syntaxe de propagation (...).

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

Cela peut sembler étrange, mais c'est assez simple. Il extrait simplement les éléments arguments et les remet dans le tableau. Si vous ne comprenez toujours pas, consultez ces exemples:

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

Notez que cela ne fonctionne pas dans certains navigateurs plus anciens comme IE 11, donc si vous voulez prendre en charge ces navigateurs, vous devez utiliser Babel.

3
répondu Michał Perłakowski 2017-08-28 15:52:12

Une Autre Réponse.

Utilisez Des Sorts De Magie Noire:

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

Firefox, Chrome, Nœud.js, IE11 sont OK.

1
répondu LightSpeedC Kazuaki Nishizawa 2014-07-10 01:24:28

Essayez d'utiliser Object.setPrototypeOf()

Explication: Set prototype de arguments à Array.prototype

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

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

Explication: prenez chaque index de arguments, Placez l'élément dans un tableau à l'index correspondant du tableau.

Peut aussi l'utiliser Array.prototype.map()

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

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

Explication: prenez chaque index de arguments, Placez l'élément dans un tableau à l'index correspondant du tableau.

for..of boucle

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()

Explication: créez un objet, définissez les propriétés de l'objet sur des éléments à chaque index de arguments; définissez prototype de l'objet créé sur 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]]]))
1
répondu guest271314 2016-02-01 19:29:59

Benshmarck 3 Méthodes:

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);

Résultat?

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

Profitez !

0
répondu Matrix 2016-01-21 10:29:47

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

document.body.innerHTML = sortArgs(1, 2, 3, 4).toString();
0
répondu Autumnswind 2016-01-29 05:47:03

Bien que les paramètres rest fonctionnent bien, si vous voulez continuer à utiliser arguments pour une raison quelconque, pensez à

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

[...arguments] peut être considéré comme une sorte d'alternative à l' Array.from(arguments), qui fonctionne également parfaitement.

Une alternative ES7 est une compréhension de tableau:

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

Cela pourrait être plus facile si vous voulez traiter ou filtrer les arguments avant le tri:

[for (i of arguments) if (i % 2) Math.log(i)].sort()
0
répondu 2016-02-01 05:11:36
 function x(){
   var rest = [...arguments]; console.log(rest);return     
   rest.constructor;
 };
 x(1,2,3)

J'ai essayé une technique de destruction simple

0
répondu Gaurav 2016-07-09 18:17:39

L'objet Arguments n'est disponible que dans un corps de fonction. Bien que vous puissiez indexer L'objet Arguments comme un tableau, ce n'est pas un tableau. Il n'a pas de propriétés de tableau autres que length.

// 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();

Bien qu'il puisse être indexé comme un tableau comme vous pouvez le voir dans cet exemple:

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));

Cependant, L'objet Arguments n'est pas un tableau et n'a pas d'autres propriétés que length.

Vous pouvez convertir le arguments objet dans un tableau à quel point vous pouvez accéder à L'objet Arguments.

Il existe de nombreuses façons d'accéder à l'objet arguments dans un corps de fonction, notamment:

  1. , vous pouvez appeler le Tableau.prototoype.tranche.appel de la méthode.

Tableau.prototype.tranche.appel(arguments)

function giveMeArgs(arg1,arg2){

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

console.log( giveMeArgs(1,2));
  1. Vous pouvez utiliser le tableau littéral

[].tranche.appel(arguments).

function giveMeArgs(arg1,arg2){

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

return args;

}

console.log( giveMeArgs(1,2) );
  1. vous peut utiliser le repos ...

function giveMeArgs(...args){

return args;

}

console.log(giveMeArgs(1,2))
  1. , vous pouvez utiliser la propagation [...]

function giveMeArgs(){

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

}

console.log(giveMeArgs(1,2));
  1. Vous pouvez utiliser Array.de ()

function giveMeArgs(){

var args = Array.from(arguments);

return args;

}

console.log(giveMeArgs(1,2));
0
répondu Rick 2017-04-23 23:35:40

Vous pouvez créer une fonction réutilisable pour le faire avec n'importe quel argument, le plus simple est quelque chose comme ceci:

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

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

La syntaxe Spread peut être utilisée dans ES6 et au-dessus...

Mais si vous souhaitez utiliser quelque chose de compatible avec ES5 et ci-dessous, vous pouvez utiliser Array.prototype.slice.call, donc votre code ressemble à ceci:

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

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

Il y a aussi peu d'autres façons de le faire, par exemple en utilisant Array.from ou en parcourant les arguments et en les assignant à un nouveau tableau...

0
répondu Alireza 2017-12-24 19:08:28

C'est une très vieille question, mais je pense avoir une solution qui est légèrement plus facile à taper que les solutions précédentes et ne repose pas sur des bibliothèques externes:

function sortArguments() {
  return Array.apply(null, arguments).sort();
}
-2
répondu HandyAndyShortStack 2013-06-18 21:02:23