it-swarm.dev

Jak mogę przekonwertować obiekt "arguments" na tablicę w JavaScript?

Obiekt arguments w JavaScript jest dziwnym brodawką - w większości sytuacji działa jak tablica, ale nie jest faktycznie obiektem tablicy. Ponieważ jest to naprawdę coś zupełnie innego , nie ma użytecznych funkcji z Array.prototype like forEach, sort, filter i map.

Łatwo jest zbudować nową tablicę z obiektu argumentów za pomocą prostej pętli for. Na przykład ta funkcja sortuje swoje argumenty:

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

Jest to jednak dość żałosna rzecz, którą trzeba zrobić, aby uzyskać dostęp do niezwykle przydatnych funkcji tablic JavaScript. Czy jest to wbudowany sposób, aby to zrobić za pomocą standardowej biblioteki?

405
Andrew Coleson

ES6 z wykorzystaniem parametrów odpoczynku

Jeśli możesz użyć ES6, możesz użyć:

Parametry odpoczynku

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

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

Jak możesz przeczytać w link

Składnia parametru rest pozwala nam reprezentować nieokreśloną liczbę argumentów jako tablicę.

Jeśli interesuje cię składnia ..., nazywa się Operator rozłożenia i możesz przeczytać więcej tutaj .

ES6 za pomocą Array.from ()

Używając 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 po prostu przekonwertuj obiekty Array-podobne lub Iterable na instancje Array. 



ES5

W rzeczywistości możesz po prostu użyć Array 's slice function na obiekcie arguments, i przekształci to w standardową tablicę JavaScript. Będziesz musiał odwołać się do niego ręcznie za pośrednictwem prototypu Array:

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

Dlaczego to działa? Oto fragment z samej dokumentacji ECMAScript 5 :

UWAGA: funkcja slice jest celowo generyczna; nie wymaga, aby jego wartość this była obiektem Array. Dlatego może być przenoszony na inne rodzaje obiektów do wykorzystania jako metoda. To, czy funkcja slice może zostać pomyślnie zastosowana do obiektu Host, zależy od implementacji.

Dlatego slice działa na wszystkim, co ma właściwość length, co arguments wygodnie robi.


Jeśli Array.prototype.slice jest dla ciebie za dużo, możesz skrócić go nieco, używając literałów tablicowych:

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

Jednak mam wrażenie, że poprzednia wersja jest bardziej jednoznaczna, więc wolałbym ją zamiast tego. Nadużywanie literalnej notacji tablicowej jest odrażające i wygląda dziwnie.

671

Warto również odwołać się do ten Bluebird obiecuje biblioteczną stronę wiki która pokazuje, jak zarządzać obiektem arguments w tablicy w sposób, który sprawia, że ​​funkcja optymalizowalna pod silnikiem JavaScript V8:

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

Ta metoda jest używana na rzecz var args = [].slice.call(arguments);. Autor pokazuje również, w jaki sposób krok budowania może pomóc w zmniejszeniu szczegółowości.

38
jbmusso
function sortArgs(){ return [].slice.call(arguments).sort() }

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

Niektóre metody tablicowe są celowo wykonywane, aby nie wymagać, aby obiekt docelowy był rzeczywistą tablicą. Wymagają jedynie, aby obiekt docelowy posiadał właściwość o nazwie length i indeksy (które muszą mieć zero lub większe liczby całkowite).

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

Posługiwać się:

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

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

Array(str1) zwraca [str1]

Array(num1) zwraca tablicę z elementami num1

Musisz sprawdzić liczbę argumentów!

Wersja Array.slice (wolniejsza):

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

Wersja Array.Push (wolniejsza, szybsza niż plasterek):

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

Przenieś wersję (wolniej, ale mały rozmiar jest szybszy):

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

Wersja Array.concat (najwolniejsza):

function sortArguments() {
  return Array.prototype.concat.apply([], arguments).sort();
}

Jeśli korzystasz z jQuery, to o wiele łatwiej jest zapamiętać w mojej opinii:

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

Oto benchmark kilku metod konwersji argumentów na tablice. 

Jeśli chodzi o mnie, najlepszym rozwiązaniem dla niewielkiej liczby argumentów jest:

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

W innych przypadkach:

function sortArgs (){ return Array.apply(null, arguments).sort(); }
5
Gheljenor

Lodash:

var args = _.toArray(arguments);

w akcji:

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

produkuje:

[2,3]
4
Zane Hooper

Użyj Array.from() , która pobiera obiekt tablicowy (taki jak arguments) jako argument i konwertuje go do tablicy:

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

Zauważ, że nie działa w niektórych starszych przeglądarkach, takich jak IE 11, więc jeśli chcesz wspierać te przeglądarki, powinieneś użyć Babel .

4

W ECMAScript 6 nie trzeba używać brzydkich hacków takich jak Array.prototype.slice(). Zamiast tego możesz użyć składni spread (...) .

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

Może wyglądać dziwnie, ale jest dość prosty. Po prostu wyodrębnia elementy arguments 'i umieszcza je z powrotem w tablicy. Jeśli nadal nie rozumiesz, zobacz te przykłady:

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

Zauważ, że nie działa w niektórych starszych przeglądarkach, takich jak IE 11, więc jeśli chcesz wspierać te przeglądarki, powinieneś użyć Babel .

4

Polecam używanie ECMAScript 6 spread operator , który powiąza końcowe parametry z tablicą. Dzięki temu rozwiązaniu nie musisz dotykać obiektu arguments, a Twój kod zostanie uproszczony. Wadą tego rozwiązania jest to, że nie działa w większości przeglądarek, więc zamiast tego będziesz musiał użyć kompilatora JS, takiego jak Babel. Pod maską Babel przekształca arguments w Array z pętlą for. 

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

Jeśli nie możesz użyć ECMAScript 6, radzę przejrzeć inne odpowiedzi, takie jak @ 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

Kolejna odpowiedź.

Użyj czarnych zaklęć:

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

Firefox, Chrome, Node.js, IE11 są w porządku.

Spróbuj użyć Object.setPrototypeOf()

Objaśnienie: Ustaw prototype z arguments na Array.prototype

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

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


Explanation: Zbierz każdy indeks arguments, umieść element w tablicy w odpowiednim indeksie tablicy.

może alternatywnie użyć Array.prototype.map()

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

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


Explanation: Zbierz każdy indeks arguments, umieść element w tablicy w odpowiednim indeksie tablicy.

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


lub Object.create()

Explanation: Utwórz obiekt, ustaw właściwości obiektu dla elementów w każdym indeksie arguments; ustaw prototype utworzonego obiektu na 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

Możesz utworzyć funkcję wielokrotnego użytku, aby zrobić to z dowolnymi argumentami, najprostszy to coś takiego: 

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

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

Składnia spreadu może być używana w ES6 i powyżej ... 

Ale jeśli chcesz użyć czegoś kompatybilnego z ES5 i poniżej, możesz użyć Array.prototype.slice.call, więc kod wygląda następująco:

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

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

Jest jeszcze kilka innych sposobów, aby to zrobić, na przykład używając Array.from lub przechodź przez argumenty i przydziel je do nowej tablicy ...

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

Próbowałem prostej techniki niszczenia

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

Obiekt Arguments jest dostępny tylko wewnątrz treści funkcji. Chociaż możesz indeksować obiekt Argumenty jak tablicę, nie jest to tablica. Nie ma żadnych właściwości tablicy poza długością. 

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

Chociaż może być indeksowany jak tablica, jak widać w tym przykładzie: 

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

Jednak obiekt Arguments nie jest tablicą i nie ma żadnych innych właściwości poza długością.

Możesz przekształcić obiekt argumentów w tablicę, w którym możesz uzyskać dostęp do obiektu Arguments. 

Istnieje wiele sposobów na uzyskanie dostępu do obiektu arguments w treści funkcji, do których należą: 

  1. możesz wywołać metodę Array.prototoype.slice.call.

Array.prototype.slice.call (argumenty) 

function giveMeArgs(arg1,arg2){

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

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

  1. możesz użyć literału tablicowego 

[] .slice.call (argumenty).

function giveMeArgs(arg1,arg2){

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

return args;

}

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

  1. możesz użyć Rest ...

function giveMeArgs(...args){

return args;

}

console.log(giveMeArgs(1,2))

  1. możesz użyć spreadu [...]

function giveMeArgs(){

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

}

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

  1. możesz użyć Array.from ()

function giveMeArgs(){

var args = Array.from(arguments);

return args;

}

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

0
Rick

Oto czyste i zwięzłe rozwiązanie:

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

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

Object.values( ) zwróci wartości obiektu jako tablicę, a ponieważ arguments jest obiektem, to zasadniczo konwertuje arguments na tablicę, zapewniając w ten sposób wszystkie funkcje pomocnicze tablicy, takie jak map, forEach, filter, itp.

0
Eternal Darkness

Chociaż parametry odpoczynku działają dobrze, jeśli chcesz nadal używać arguments z jakiegoś powodu, rozważ

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

[...arguments] można uznać za rodzaj alternatywy dla Array.from(arguments), która również działa doskonale. 

Alternatywa ES7 to zrozumienie tablicy:

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

To może być najłatwiejsze, jeśli chcesz przetworzyć lub przefiltrować argumenty przed sortowaniem:

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

Metody Benshmarcka 3:

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

WYNIK?

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

Cieszyć się !

0
Matrix