varargs passed length javascript arrays sorting arguments variadic-functions

passed - javascript get function arguments



¿Cómo puedo convertir el objeto de "argumentos" a una matriz en JavaScript? (20)

ES6 usando los parámetros de descanso

Si puedes usar ES6 puedes usar:

Parámetros de descanso

function sortArgs(...args) { return args.sort(function (a, b) { return a - b; }); } document.body.innerHTML = sortArgs(12, 4, 6, 8).toString();

Como podéis leer en el enlace.

La sintaxis del resto de parámetros nos permite representar un número indefinido de argumentos como una matriz.

Si tiene curiosidad por la ... sintaxis, se llama Operador de propagación y puede leer más here .

ES6 utilizando array.from ()

Utilizando 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 simplemente convierte objetos parecidos a Array o iterables en instancias de Array.

ES5

En realidad, solo puede usar la función de Array de Array en un objeto de argumentos, y la convertirá en una matriz de JavaScript estándar. Solo tendrás que referenciarlo manualmente a través del prototipo de Array:

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

¿Por qué funciona esto? Bueno, aquí hay un extracto de la documentación de ECMAScript 5 en sí :

NOTA : La función de slice es intencionalmente genérica; no requiere que este valor sea un objeto Array. Por lo tanto, se puede transferir a otros tipos de objetos para utilizarlos como método. Si la función de slice se puede aplicar con éxito a un objeto host depende de la implementación.

Por lo tanto, slice funciona en cualquier cosa que tenga una propiedad de length , lo que los arguments convenientemente.

Si Array.prototype.slice es demasiado para usted, puede abreviarlo ligeramente usando matrices literales:

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

Sin embargo, tiendo a sentir que la versión anterior es más explícita, por lo que prefiero en su lugar. Abusar de la notación literal de matriz se siente intrépido y parece extraño.

El objeto de arguments en JavaScript es una verruga rara: actúa como una matriz en la mayoría de las situaciones, pero en realidad no es un objeto de matriz. Como realmente es algo completamente distinto , no tiene las funciones útiles de Array.prototype como forEach , sort , filter y map .

Resulta trivialmente fácil construir una nueva matriz a partir de un objeto de argumentos con un simple bucle for. Por ejemplo, esta función ordena sus argumentos:

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

Sin embargo, esto es algo lamentable que se debe hacer simplemente para obtener acceso a las funciones de matriz de JavaScript extremadamente útiles. ¿Hay una forma integrada de hacerlo utilizando la biblioteca estándar?


Aunque los parámetros de descanso funcionan bien, si desea continuar usando arguments por alguna razón, considere

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

[...arguments] puede considerarse una especie de alternativa a Array.from(arguments) , que también funciona perfectamente bien.

Una alternativa de ES7 es una comprensión de matriz:

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

Esto podría ser más fácil si desea procesar o filtrar los argumentos antes de ordenar:

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


Benshmarck 3 métodos:

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

¿RESULTADO?

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

Disfrutar


El objeto Argumentos solo está disponible dentro de un cuerpo de función. Aunque puede indexar el objeto Argumentos como una matriz, no es una matriz. No tiene ninguna propiedad de matriz que no sea la longitud.

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

Aunque se puede indexar como una matriz, como puede ver en este ejemplo:

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

Sin embargo, el objeto Argumentos no es una matriz y no tiene ninguna otra propiedad que no sea la longitud.

Puede convertir el objeto de argumentos en una matriz, en cuyo punto puede acceder al objeto Argumentos.

Hay muchas formas de acceder al objeto de argumentos dentro del cuerpo de una función, y estas incluyen:

  1. puede llamar al método Array.prototoype.slice.call.

Array.prototype.slice.call (argumentos)

function giveMeArgs(arg1,arg2){ var args = Array.prototype.slice.call(arguments); return args } console.log( giveMeArgs(1,2));

  1. puedes usar el array literal

[] .slice.call (argumentos).

function giveMeArgs(arg1,arg2){ var args = [].slice.call(arguments); return args; } console.log( giveMeArgs(1,2) );

  1. puedes usar Rest ...

function giveMeArgs(...args){ return args; } console.log(giveMeArgs(1,2))

  1. Puedes usar spread [...]

function giveMeArgs(){ var args = [...arguments]; return args; } console.log(giveMeArgs(1,2));

  1. puedes usar Array.from ()

function giveMeArgs(){ var args = Array.from(arguments); return args; } console.log(giveMeArgs(1,2));


En ECMAScript 6 no hay necesidad de usar hacks feos como Array.prototype.slice() . En su lugar puede utilizar here .

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

Puede parecer extraño, pero es bastante simple. Simplemente extrae los elementos de los arguments y los vuelve a colocar en la matriz. Si aún no entiendes, mira estos ejemplos:

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

Tenga en cuenta que no funciona en algunos navegadores más antiguos como IE 11, por lo que si desea admitir estos navegadores, debe usar Babel .


Esta es una pregunta muy antigua, pero creo que tengo una solución que es un poco más fácil de escribir que las soluciones anteriores y no se basa en bibliotecas externas:

function sortArguments() { return Array.apply(null, arguments).sort(); }


Intente usar Object.setPrototypeOf()

Explicación: Establecer prototype de arguments en Array.prototype

function toArray() { return Object.setPrototypeOf(arguments, Array.prototype) } console.log(toArray("abc", 123, {def:456}, [0,[7,[14]]]))

Explicación: tome cada índice de arguments , coloque el elemento en una matriz en el índice correspondiente de la matriz.

podría alternativamente usar Array.prototype.map()

function toArray() { return [].map.call(arguments, (_,k,a) => a[k]) } console.log(toArray("abc", 123, {def:456}, [0,[7,[14]]]))

Explicación: tome cada índice de arguments , coloque el elemento en una matriz en el índice correspondiente de la matriz.

for..of bucle

function toArray() { let arr = []; for (let prop of arguments) arr.push(prop); return arr } console.log(toArray("abc", 123, {def:456}, [0,[7,[14]]]))

o Object.create()

Explicación: Cree un objeto, establezca las propiedades del objeto en elementos en cada índice de arguments ; establecer prototype de objeto creado en 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]]]))


Lodash:

var args = _.toArray(arguments);

en acción:

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

produce:

[2,3]


Otra respuesta.

Usa Hechizos de Magia Negra:

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

Firefox, Chrome, Node.js, IE11 están bien.


Puedes crear una función reutilizable para hacerlo con cualquier argumento, la más simple es algo como esto:

function sortArgs() { return [...arguments].sort(); } sortArgs(''ali'', ''reza'', 1, 2, ''a''); //[1, 2, "a", "ali", "reza"];

La sintaxis de propagación se puede utilizar en ES6 y superiores ...

Pero si desea usar algo compatible con ES5 y más abajo, puede usar Array.prototype.slice.call , por lo que el código se ve así:

function sortArgs() { return Array.prototype.slice.call(arguments).sort(); } sortArgs(''ali'', ''reza'', 1, 2, ''a''); //[1, 2, "a", "ali", "reza"];

También hay algunas otras formas de hacerlo, por ejemplo, utilizando Array.from o Array.from los argumentos y asignándolos a una nueva matriz ...


Recomiendo usar el here ECMAScript 6, que vinculará los parámetros finales a una matriz. Con esta solución, no necesita tocar el objeto de arguments y su código se simplificará. El inconveniente de esta solución es que no funciona en la mayoría de los navegadores, por lo que, en cambio, tendrá que usar un compilador JS como Babel. Bajo el capó, Babel transforma los arguments en un Array con un bucle for.

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

Si no puede usar un ECMAScript 6, recomiendo mirar algunas de las otras respuestas, como @Jonathan Fingland

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


Si está usando jQuery, lo que sigue es mucho más fácil de recordar, en mi opinión:

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


También vale la pena hacer referencia a esta página wiki de la biblioteca de promesas de Bluebird que muestra cómo administrar los arguments objeto en una matriz de una manera que hace que la función sea optimizable en el motor de JavaScript V8 :

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

Este método se utiliza a favor de var args = [].slice.call(arguments); . El autor también muestra cómo un paso de compilación puede ayudar a reducir la verbosidad.


Use array.from , que toma un objeto similar a una matriz (como arguments ) como argumento y lo convierte en matriz:

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

Tenga en cuenta que no funciona en algunos navegadores más antiguos como IE 11, por lo que si desea admitir estos navegadores, debe usar Babel .


Utilizar:

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

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

Array(str1) devuelve [str1]

Array(num1) devuelve una matriz que tiene elementos num1

Debe comprobar el número de argumentos!

Versión de Array.slice (más lenta):

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

Versión de Array.push (más lenta, más rápida que un corte):

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

Mover la versión (más lento, pero el tamaño pequeño es más rápido):

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

Versión Array.concat (la más lenta):

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


Aquí está el punto de referencia de varios métodos de conversión de argumentos en matriz.

En cuanto a mí, la mejor solución para una pequeña cantidad de argumentos es:

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

Para otros casos:

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


function sortArgs(...args) { return args.sort(function (a, b) { return a - b; }); } document.body.innerHTML = sortArgs(1, 2, 3, 4).toString();


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

Intenté la técnica de destrucción simple


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


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

Algunos métodos de matriz se hacen intencionalmente para no requerir que el objeto de destino sea una matriz real. Solo requieren que el objetivo tenga una propiedad denominada longitud e índices (que deben ser cero o enteros más grandes).

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