Hvordan kan jeg konvertere "argumenter" objekt til en matrise i Javascript?

stemmer
389

Den argumentsobjekt i Javascript er en merkelig vorte-det fungerer akkurat som en matrise i de fleste situasjoner, men det er ikke egentlig en rekke objekt. Siden det er virkelig noe helt annet , det har ikke de nyttige funksjoner fra Array.prototypelignende forEach, sort, filter, og map.

Det er trivielt enkelt å konstruere en ny rekke fra en argumentene objektet med en enkel løkke for. For eksempel denne funksjonen sorterer sine argumenter:

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

Men dette er en ganske ynkelig ting å ha å gjøre bare for å få tilgang til de svært nyttige Javascript array funksjoner. Er det en innebygd måte å gjøre det ved hjelp av standard bibliotek?

Publisert på 07/06/2009 klokken 00:08
kilden bruker
På andre språk...                            


21 svar

stemmer
642

ES6 ved anvendelse av hvile parametere

Hvis du er i stand til å bruke ES6 kan du bruke:

Rest Parametere

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

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

Som du kan lese i linken

Resten parameter syntaks tillater oss å representere et ubestemt antall argumenter som en matrise.

Hvis du er nysgjerrig på ...syntaks, kalles det Spread Operatør og du kan lese mer her .

ES6 ved hjelp array.from ()

Bruke 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 bare konvertere Array-lignende eller Iterable gjenstander inn Array tilfeller.



ES5

Du kan faktisk bare bruke Arraysin slicefunksjon på en av argumentene objektet, og det vil konvertere den til en Javascript-matrise standard. Du må bare referere til den manuelt via Array prototype:

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

Hvorfor virker dette? Vel, her er et utdrag fra ECMAScript 5 dokumentasjon seg selv :

MERK : Den slicefunksjonen er vilje generisk; det krever ikke at det denne verdien være en Array objekt. Derfor kan det overføres til andre typer gjenstander til bruk som metode. Hvorvidt slicefunksjonen kan brukes med hell til en rekke formål er gjennomføring avhengig.

Derfor slicefungerer på alt som har en lengtheiendom, som argumentsbeleilig gjør.


Hvis Array.prototype.sliceer for mye av en munnfull for deg, kan du forkorte den litt ved å bruke array-litteraler:

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

Men jeg har en tendens til å føle at den tidligere versjonen er mer eksplisitt, så jeg foretrekker det i stedet. Misbruker matrisen bokstavelig notasjon føles Hacky og ser merkelig ut.

Svarte 07/06/2009 kl. 00:10
kilden bruker

stemmer
9

Hvis du bruker jQuery, er følgende en god del lettere å huske etter min mening:

function sortArgs(){
  return $.makeArray(arguments).sort();
}
Svarte 07/06/2009 kl. 00:19
kilden bruker

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

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

Noen array-metoder er med hensikt laget for ikke å kreve målobjektet for å være en faktisk matrise. De krever bare målet å ha en eiendom som heter lengde og indekser (som må være null eller større heltall).

[].sort.call({0:1, 1:0, length:2}) // => ({0:0, 1:1, length:2})
Svarte 09/06/2009 kl. 18:29
kilden bruker

stemmer
-2

Dette er en svært gammel spørsmålet, men jeg tror jeg har en løsning som er litt lettere å skrive enn tidligere løsninger og ikke er avhengig av eksterne bibliotek:

function sortArguments() {
  return Array.apply(null, arguments).sort();
}
Svarte 18/06/2013 kl. 21:02
kilden bruker

stemmer
4

Her er målestokk av flere metoder omdanner argumenter inn i matrisen.

Som for meg, den beste løsningen for liten mengde argumenter er:

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

For andre tilfeller:

function sortArgs (){ return Array.apply(null, arguments).sort(); }
Svarte 03/07/2013 kl. 09:05
kilden bruker

stemmer
12

Bruk:

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

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

Array(str1) avkastning [str1]

Array(num1)returnerer en matrise som har num1elementer

Du må sjekke antall argumenter!

Array.slice versjon (langsommere):

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

Array.push versjon (langsommere, raskere enn skive):

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

Flytt versjon (tregere, men liten størrelse er raskere):

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

Array.concat version (tregeste):

function sortArguments() {
  return Array.prototype.concat.apply([], arguments).sort();
}
Svarte 27/10/2013 kl. 14:39
kilden bruker

stemmer
36

Det er også verdt å registrere dette Bluebird løfter bibliotek wikiside som viser hvordan å håndtere argumentsobjektet inn matrisen på en måte som gjør funksjonen optimaliserbar henhold V8 Javascript-motoren :

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

Denne metoden brukes til fordel for var args = [].slice.call(arguments);. Forfatteren viser også hvordan en bygge trinnet kan bidra til å redusere detaljnivå.

Svarte 03/06/2014 kl. 09:11
kilden bruker

stemmer
1

Et annet svar.

Bruk Black Magic Spells:

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

Firefox, Chrome, node.js, IE11 er OK.

Svarte 10/07/2014 kl. 01:24
kilden bruker

stemmer
0

Benshmarck 3 metoder:

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

RESULTAT?

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

Nyt !

Svarte 25/07/2014 kl. 01:02
kilden bruker

stemmer
3

I ECMAScript 6 er det ikke nødvendig å bruke stygge hacks som Array.prototype.slice(). Du kan i stedet bruke spread syntaks ( ...) .

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

Det kan se rart ut, men det er ganske enkel. Det bare ekstrakter arguments'elementer og sette dem tilbake i matrisen. Hvis du fortsatt ikke forstår, se denne eksempler:

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

Legg merke til at det ikke fungerer i noen eldre nettlesere som IE 11, så hvis du ønsker å støtte disse nettleserne, bør du bruke Babel .

Svarte 24/01/2016 kl. 17:04
kilden bruker

stemmer
4

I anbefaler å bruke ECMAScript 6 spredning operatør , som vil binde etterfølgende parametere til en matrise. Med denne løsningen trenger du ikke å berøre argumentsobjektet og koden din vil bli forenklet. Ulempen med denne løsningen er at det ikke fungerer i de fleste nettlesere, så i stedet må du bruke en JS kompilator som Babel. Under panseret Babel forvandles argumentstil en Array med en for loop.

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

Hvis du ikke kan bruke en ECMAScript 6, anbefaler jeg å se på noen av de andre svarene som @Jonathan Fingland

function sortArgs() {
    var args = Array.prototype.slice.call(arguments);
    return args.sort();
}
Svarte 25/01/2016 kl. 21:51
kilden bruker

stemmer
4

Bruk Array.from(), som tar en matrise-lignende gjenstand (for eksempel arguments) som argument, og omdanner det til matrisen:

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

Legg merke til at det ikke fungerer i noen eldre nettlesere som IE 11, så hvis du ønsker å støtte disse nettleserne, bør du bruke Babel .

Svarte 26/01/2016 kl. 09:00
kilden bruker

stemmer
0

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

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

Svarte 29/01/2016 kl. 05:47
kilden bruker

stemmer
1

Prøv å bruke Object.setPrototypeOf()

Forklaring: Sett prototypeav argumentstilArray.prototype

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

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


Forklaring: Ta hver indeks på arguments, plass element inn i en rekke, på tilsvarende indeks på matrisen.

alternativt kunne bruke Array.prototype.map()

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

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


Forklaring: Ta hver indeks på arguments, plass element inn i en rekke, på tilsvarende indeks på matrisen.

for..of sløyfe

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

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


eller Object.create()

Forklaring: Opprett objekt, sette egenskapene til objekt til elementer på hver indeks over arguments; satt prototypeav laget objekt tilArray.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]]]))

Svarte 30/01/2016 kl. 02:11
kilden bruker

stemmer
0

Selv om resten parametere fungerer bra, hvis du ønsker å fortsette å bruke argumentsen eller annen grunn, anser

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

[...arguments]kan betraktes som en slags alternativ til Array.from(arguments), som også fungerer utmerket godt.

En ES7 alternativ er en matrise forståelse:

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

Dette kan være lettest hvis du ønsker å behandle eller filtrere argumentene før sortering:

[for (i of arguments) if (i % 2) Math.log(i)].sort()
Svarte 30/01/2016 kl. 19:45
kilden bruker

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

Jeg prøvde enkle ødeleggende teknikk

Svarte 09/07/2016 kl. 18:17
kilden bruker

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

Svarte 11/09/2016 kl. 13:26
kilden bruker

stemmer
4

Lodash:

var args = _.toArray(arguments);

i aksjon:

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

produserer:

[2,3]
Svarte 04/10/2016 kl. 23:41
kilden bruker

stemmer
0

Argumentene gjenstand er bare tilgjengelig inne en funksjon legeme. Selv om du kan indeksere argumentene objektet som en matrise, er det ikke en matrise. Det har ingen andre enn lengden array-egenskaper.

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

Selv om det kan indekseres som en matrise som du kan se i dette eksempelet:

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

Imidlertid er argumentene objektet ikke en matrise, og ikke har noen andre egenskaper enn lengde.

Du kan konvertere argumentene objektet inn i en matrise og da kan du få tilgang argumentene objektet.

Det er mange måter du kan få tilgang argumentene objektet inne i en funksjon kroppen, og disse inkluderer:

  1. kan du ringe Array.prototoype.slice.call metoden.

Array.prototype.slice.call (arguments)

function giveMeArgs(arg1,arg2){

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

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

  1. du kan bruke array bokstave

[] .Slice.call (arguments).

function giveMeArgs(arg1,arg2){

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

return args;

}

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

  1. du kan bruke Rest ...

function giveMeArgs(...args){

return args;

}

console.log(giveMeArgs(1,2))

  1. du kan bruke spre [...]

function giveMeArgs(){

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

}

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

  1. du kan bruke Array.from ()

function giveMeArgs(){

var args = Array.from(arguments);

return args;

}

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

Svarte 22/04/2017 kl. 00:41
kilden bruker

stemmer
0

Du kan opprette en gjenbrukbar funksjon for å gjøre det med noen argumenter, er det enkleste en noe sånt som dette:

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

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

Spread syntaks kan brukes i ES6 og over ...

Men hvis du ønsker å bruke noe kompatibel med ES5 og under, kan du bruke Array.prototype.slice.call, slik at du koden ser slik ut:

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

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

Det finnes også andre måter å gjøre dette på, for eksempel ved anvendelse Array.fromeller sløyfe gjennom argumenter og tilordne dem til en ny matrise ...

Svarte 24/12/2017 kl. 12:35
kilden bruker

stemmer
0

Her er en ren og konsist løsning:

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

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

Object.values( )vil returnere verdiene av et objekt som en matrise, og siden argumentser et objekt, vil det i hovedsak konvertere argumentstil en matrise, og dermed gi deg alle en tabellens hjelpefunksjoner som map, forEach, filter, etc.

Svarte 12/02/2019 kl. 23:10
kilden bruker

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more