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?
Si vous pouvez 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 et vous pouvez en lire davantage ici .
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.
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 fonctionslice
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.
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é.
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})
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();
}
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(); }
Lodash:
var args = _.toArray(arguments);
en action:
(function(){ console.log(_.toArray(arguments).splice(1)); })(1, 2, 3)
produit:
[2,3]
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 .
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 .
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();
}
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));
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]]]))
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]]]))
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 ...
function x(){
var rest = [...arguments]; console.log(rest);return
rest.constructor;
};
x(1,2,3)
J'ai essayé une technique de destruction simple
function sortArgs(...args) {
return args.sort(function (a, b) { return a - b; });
}
document.body.innerHTML = sortArgs(1, 2, 3, 4).toString();
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:
Array.prototype.slice.call (arguments)
function giveMeArgs(arg1,arg2){
var args = Array.prototype.slice.call(arguments);
return args
}
console.log( giveMeArgs(1,2));
[] .slice.call (arguments).
function giveMeArgs(arg1,arg2){
var args = [].slice.call(arguments);
return args;
}
console.log( giveMeArgs(1,2) );
function giveMeArgs(...args){
return args;
}
console.log(giveMeArgs(1,2))
function giveMeArgs(){
var args = [...arguments];
return args;
}
console.log(giveMeArgs(1,2));
function giveMeArgs(){
var args = Array.from(arguments);
return args;
}
console.log(giveMeArgs(1,2));
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.
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()
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 !