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?
20 réponses
ES6 en utilisant les paramètres rest
Si vous êtes capable D'utiliser ES6, vous pouvez utiliser:
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 fonctionslice
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.
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é.
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})
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();
}
Si vous utilisez jQuery, ce qui suit est beaucoup plus facile à retenir à mon avis:
function sortArgs(){
return $.makeArray(arguments).sort();
}
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(); }
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();
}
Lodash:
var args = _.toArray(arguments);
En action:
(function(){ console.log(_.toArray(arguments).splice(1)); })(1, 2, 3)
Produit:
[2,3]
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.
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));
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.
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.
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]]]))
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]]]))
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 !
function sortArgs(...args) {
return args.sort(function (a, b) { return a - b; });
}
document.body.innerHTML = sortArgs(1, 2, 3, 4).toString();
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()
function x(){
var rest = [...arguments]; console.log(rest);return
rest.constructor;
};
x(1,2,3)
J'ai essayé une technique de destruction simple
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:
- , 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));
- 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) );
- vous peut utiliser le repos ...
function giveMeArgs(...args){
return args;
}
console.log(giveMeArgs(1,2))
- , vous pouvez utiliser la propagation [...]
function giveMeArgs(){
var args = [...arguments];
return args;
}
console.log(giveMeArgs(1,2));
- Vous pouvez utiliser Array.de ()
function giveMeArgs(){
var args = Array.from(arguments);
return args;
}
console.log(giveMeArgs(1,2));
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...
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();
}