it-swarm.com.ru

Как я могу преобразовать объект "arguments" в массив в JavaScript?

Объект arguments в JavaScript - это странная бородавка - в большинстве случаев он действует как массив, но на самом деле это не фактически объект массива. Поскольку это действительно что-то еще целиком , у него нет полезных функций из Array.prototype вроде forEach, sort, filter и map.

Тривиально легко создать новый массив из объекта аргументов с простым циклом for. Например, эта функция сортирует свои аргументы:

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

Однако это довольно жалкая вещь, которую нужно сделать, просто чтобы получить доступ к чрезвычайно полезным функциям массива JavaScript. Есть ли встроенный способ сделать это с помощью стандартной библиотеки?

405
Andrew Coleson

ES6 с использованием остальных параметров

Если вы можете использовать ES6, вы можете использовать:

Параметры покоя

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

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

Как вы можете прочитать в ссылка

Синтаксис остальных параметров позволяет нам представлять неопределенное количество аргументов в виде массива.

Если вам интересен синтаксис ..., он называется Оператор распространения, и вы можете прочитать больше здесь .

ES6 с использованием Array.from ()

Используя 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 просто преобразует объекты типа Array или Iterable в экземпляры Array. 



ES5

На самом деле вы можете просто использовать функцию Array's slice для объекта аргументов, и она преобразует его в стандартный массив JavaScript. Вам просто нужно ссылаться на него вручную через прототип Array:

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

Почему это работает? Ну, вот выдержка из документации самого ECMAScript 5 :

NOTE: функция slice специально сделана не привязанной к типу; он не требует, чтобы его значение this было объектом Array. Поэтому его можно передавать другим объектам для использования в качестве метода. Возможность успешного применения функции slice к объекту Host зависит от реализации.

Следовательно, slice работает со всем, что имеет свойство length, что удобно делать arguments.


Если Array.prototype.slice слишком много для вас, вы можете немного его сократить, используя литералы массива:

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

Однако я склонен считать, что предыдущая версия более явная, поэтому я бы предпочел ее. Злоупотребление массивом буквенной нотации кажется хакерским и выглядит странно.

671
Jonathan Fingland

Также стоит сослаться на на этой вики-странице библиотеки обещаний Bluebird , которая показывает, как управлять объектом arguments в массив таким образом, чтобы сделать функцию оптимизируемой под движком JavaScript V8:

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

Этот метод используется в пользу var args = [].slice.call(arguments);. Автор также показывает, как шаг сборки может помочь уменьшить детализацию.

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

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

Некоторые методы массива специально созданы, чтобы не требовать, чтобы целевой объект был фактическим массивом. Они только требуют, чтобы у цели было свойство с именем length и индексами (которые должны быть нулевыми или большими целыми числами).

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

Использование:

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

Array(arg1, arg2, ...) возвращает [arg1, arg2, ...]

Array(str1) возвращает [str1]

Array(num1) возвращает массив, содержащий элементы num1

Вы должны проверить количество аргументов!

Array.slice версия (медленнее):

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

Array.Push версия (медленнее, быстрее, чем ломтик):

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

Переместить версию (медленнее, но маленький размер быстрее):

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

Array.concat версия (самая медленная):

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

Если вы используете jQuery, то, на мой взгляд, гораздо легче запомнить следующее:

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

Вот тест нескольких методов, конвертирующих аргументы в массив. 

Как по мне, лучшее решение для небольшого количества аргументов:

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

Для других случаев:

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

Lodash:

var args = _.toArray(arguments);

в бою:

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

производит:

[2,3]
4
Zane Hooper

Используйте Array.from() , которая принимает массивоподобный объект (такой как arguments) в качестве аргумента и преобразует его в массив:

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

Обратите внимание, что он не работает в некоторых старых браузерах, таких как IE 11, поэтому, если вы хотите поддерживать эти браузеры, вы должны использовать Babel .

4
Michał Perłakowski

В ECMAScript 6 нет необходимости использовать уродливые хаки, такие как Array.prototype.slice(). Вместо этого вы можете использовать распространять синтаксис (...) .

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

Это может выглядеть странно, но это довольно просто. Он просто извлекает элементы arguments и помещает их обратно в массив. Если вы все еще не понимаете, посмотрите эти примеры:

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

Обратите внимание, что он не работает в некоторых старых браузерах, таких как IE 11, поэтому, если вы хотите поддерживать эти браузеры, вы должны использовать Babel .

4
Michał Perłakowski

Я рекомендую использовать ECMAScript 6 оператор распространения , который будет привязывать конечные параметры к массиву. С этим решением вам не нужно прикасаться к объекту arguments, и ваш код будет упрощен. Недостатком этого решения является то, что оно не работает в большинстве браузеров, поэтому вместо этого вам придется использовать JS-компилятор, такой как Babel. Под капотом Babel преобразует arguments в массив с циклом for. 

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

Если вы не можете использовать ECMAScript 6, я рекомендую взглянуть на некоторые другие ответы, такие как @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

Еще один ответ.

Используйте чёрные магические заклинания:

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

Firefox, Chrome, Node.js, IE11 в порядке.

1

Попробуйте использовать Object.setPrototypeOf()

Объяснение: Установите prototype из arguments в Array.prototype

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

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


Объяснение: Возьмите каждый индекс arguments, поместите элемент в массив с соответствующим индексом массива.

в качестве альтернативы можно использовать Array.prototype.map()

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

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


Объяснение: Возьмите каждый индекс arguments, поместите элемент в массив с соответствующим индексом массива.

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


или Object.create()

Объяснение: Создать объект, установить свойства объекта для элементов с каждым индексом arguments; установите prototype созданного объекта в 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

Вы можете создать функцию многократного использования, чтобы сделать это с любыми аргументами, самый простой из которых выглядит примерно так: 

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

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

Синтаксис распространения может использоваться в ES6 и выше ... 

Но если вы хотите использовать что-то совместимое с ES5 и ниже, вы можете использовать Array.prototype.slice.call, поэтому ваш код выглядит следующим образом:

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

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

Есть также несколько других способов сделать это, например, с помощью Array.from или перебрать arguments и назначить их новому массиву ...

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

Я попробовал простую технику разрушения

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

Объект Arguments доступен только внутри тела функции. Хотя вы можете индексировать объект Arguments как массив, это не массив. Он не имеет никаких свойств массива, кроме длины. 

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

Хотя он может быть проиндексирован как массив, как вы можете видеть в этом примере: 

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

Однако объект Arguments не является массивом и не имеет никаких других свойств, кроме length.

Вы можете преобразовать объект arguments в массив, после чего вы сможете получить доступ к объекту Arguments. 

Есть много способов получить доступ к объекту arguments внутри тела функции, и они включают в себя: 

  1. вы можете вызвать метод Array.prototoype.slice.call.

Array.prototype.slice.call (аргументы) 

function giveMeArgs(arg1,arg2){

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

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

  1. вы можете использовать массив буквальный 

[] .Slice.call (аргументы).

function giveMeArgs(arg1,arg2){

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

return args;

}

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

  1. вы можете использовать Отдых ...

function giveMeArgs(...args){

return args;

}

console.log(giveMeArgs(1,2))

  1. вы можете использовать распространение [...]

function giveMeArgs(){

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

}

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

  1. вы можете использовать Array.from ()

function giveMeArgs(){

var args = Array.from(arguments);

return args;

}

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

0
Rick

Вот чистое и краткое решение:

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

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

Object.values( ) будет возвращать значения объекта в виде массива, а поскольку arguments является объектом, он по существу преобразует arguments в массив, предоставляя вам все вспомогательные функции массива, такие как map, forEach, filter, и т.п.

0
Eternal Darkness

Хотя остальные параметры работают хорошо, если вы хотите продолжать использовать arguments по какой-то причине, подумайте

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

[...arguments] можно рассматривать как своего рода альтернативу Array.from(arguments), которая также отлично работает. 

Альтернатива ES7 - это понимание массива:

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

Это может быть проще, если вы хотите обработать или отфильтровать аргументы перед сортировкой:

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

Беншмарк 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);

РЕЗУЛЬТАТ?

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

Наслаждайтесь !

0
Matrix