web-dev-qa-db-fra.com

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

L'objet arguments en JavaScript est une étrange verrue: il agit comme un tableau dans la plupart des situations, mais il ne s'agit pas d'un objet de type réellement. Puisqu'il s'agit de vraiment quelque chose d'autre , il n'a pas les fonctions utiles de Array.prototype comme forEach, sort, filter et map.

Il est très 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, c’est une 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?

405
Andrew Coleson

ES6 utilisant des paramètres de repos

Si vous pouvez utiliser ES6, vous pouvez utiliser:

PARAM&EGRAVE;TRES DE REPOS

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 et vous pouvez en lire davantage ici .

ES6 utilisant Array.from ()

Utilisation de 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 convertit simplement les objets de type tableau ou itérables en instances de tableau. 



ES5

En fait, vous pouvez simplement utiliser la fonction Array de slice sur un objet arguments et le convertira en un tableau JavaScript standard. Il vous suffira de le référencer manuellement via le prototype d'Array:

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

Pourquoi ça marche? Voici un extrait de la documentation ECMAScript 5 elle-même }:

NOTE: la fonction slice est intentionnellement générique; il n'est pas nécessaire que sa valeur this soit un objet Array. Par conséquent, il peut être transféré à d'autres types d'objets pour être utilisé comme méthode. Que la fonction slice puisse ou non être appliquée avec succès à un objet Host dépend de l'implémentation.

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


Si Array.prototype.slice est trop volumineux 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, je la préférerais donc. Abuser de la notation littérale tableau semble hacky et semble étrange.

671

Il est également intéressant de référencer cette page Bluebird promises de la bibliothèque qui montre comment gérer l'objet arguments dans un tableau de manière à rendre la fonction optimisable sous le moteur JavaScript V8:

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é.

38
jbmusso
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 créées 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 index (qui doivent être des entiers nuls ou supérieurs).

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

Utilisation:

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

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

Array(str1) renvoie [str1]

Array(num1) renvoie un tableau avec num1 éléments

Vous devez vérifier le nombre d'arguments!

Version Array.slice (plus lente):

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

Version Array.Push (plus lente, plus rapide que la tranche):

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

Déplacer la version (plus lente, mais 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();
}

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

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

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(); }
5
Gheljenor

Lodash:

var args = _.toArray(arguments);

en action:

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

produit:

[2,3]
4
Zane Hooper

Utilisez Array.from() , qui prend un objet de type tableau (tel que arguments) en 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 tels que IE 11, donc si vous voulez supporter ces navigateurs, vous devez utiliser Babel .

4

Dans ECMAScript 6, il n’est pas nécessaire d’utiliser des hacks laids comme Array.prototype.slice(). Vous pouvez également utiliser la syntaxe spread (...) .

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

Cela peut paraître étrange, mais c'est assez simple. Il extrait simplement les éléments arguments 'et les replace dans le tableau. Si vous ne comprenez toujours pas, voyez 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 tels que IE 11, donc si vous voulez supporter ces navigateurs, vous devez utiliser Babel .

4

Je recommande d'utiliser ECMAScript 6 spread operator , qui lie 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 avec la plupart des navigateurs. Vous devrez donc utiliser un compilateur JS tel que 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 ECMAScript 6, je vous recommande d’examiner d’autres réponses telles que @Jonathan Fingland.

function sortArgs() {
    var args = Array.prototype.slice.call(arguments);
    return args.sort();
}
4
jjbskir
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
Abk

Une autre réponse.

Utilisez des sorts de magie noire:

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

Firefox, Chrome, Node.js, IE11 sont OK.

Essayez d’utiliser Object.setPrototypeOf()

Explanation: Définissez prototype of arguments sur Array.prototype

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

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


Explanation: Prenez chaque index de arguments, placez item dans un tableau à l'index correspondant du tableau.

pourrait alternativement utiliser Array.prototype.map()

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

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


Explanation: Prenez chaque index de arguments, placez item dans un tableau à l'index correspondant du tableau.

for..of loop

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éer un objet, définir les propriétés de l'objet sur les éléments de chaque index de arguments; définir prototype de l'objet créé à 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
guest271314

Vous pouvez créer une fonction réutilisable pour le faire avec n'importe quel argument, le plus simple ressemble à 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 supérieur ... 

Mais si vous souhaitez utiliser quelque chose de compatible avec ES5 et inférieur, vous pouvez utiliser Array.prototype.slice.call, afin que 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 quelques autres moyens de le faire, par exemple en utilisant Array.from ou en boucle à travers les argumentset en les affectant à un nouveau tableau ...

0
Alireza
 function x(){
   var rest = [...arguments]; console.log(rest);return     
   rest.constructor;
 };
 x(1,2,3)

J'ai essayé une technique de destruction simple

0
Gaurav

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

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

0
Autumnswind

L'objet Arguments est uniquement disponible 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 d'autres propriétés de tableau que la longueur. 

// 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 aucune autre propriété que la longueur.

Vous pouvez convertir l'objet arguments en un tableau auquel accéder à l'objet Arguments. 

Vous pouvez accéder à l’argument arguments à l’intérieur d’un corps de fonction de nombreuses façons, notamment: 

  1. vous pouvez appeler la méthode Array.prototoype.slice.call.

Array.prototype.slice.call (arguments) 

function giveMeArgs(arg1,arg2){

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

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

  1. vous pouvez utiliser le littéral de tableau 

[] .slice.call (arguments).

function giveMeArgs(arg1,arg2){

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

return args;

}

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

  1. vous pouvez 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.from ()

function giveMeArgs(){

var args = Array.from(arguments);

return args;

}

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

0
Rick

Voici une solution propre et concise:

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

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

Object.values( ) renverra les valeurs d'un objet sous forme de tableau, et comme arguments est un objet, il convertira essentiellement arguments en tableau, vous fournissant ainsi toutes les fonctions d'assistance d'un tableau telles que map, forEach, filter etc.

0
Eternal Darkness

Bien que les paramètres de repos fonctionnent bien, si vous souhaitez continuer à utiliser arguments pour une raison quelconque, considérez

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

[...arguments] peut être considéré comme une alternative à 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 simple si vous souhaitez traiter ou filtrer les arguments avant le tri:

[for (i of arguments) if (i % 2) Math.log(i)].sort()
0
user663031

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

Prendre plaisir !

0
Matrix