JavaScript中的arguments对象是一个奇怪的东西——它在大多数情况下就像一个数组,但实际上它不是一个数组对象。因为它是完全不同的东西,它没有数组中的有用函数。比如forEach, sort, filter和map。

用简单的for循环从arguments对象构造一个新数组非常简单。例如,这个函数对它的参数进行排序:

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

然而,仅仅为了访问非常有用的JavaScript数组函数,就必须这么做,这是一件相当可怜的事情。是否有一种内置的方法来使用标准库?


当前回答

在ECMAScript 6中,不需要使用像Array.prototype.slice()这样丑陋的hack。您可以使用扩展语法(…)。

(函数(){ console.log(参数[…]); }(1,2,3))

这看起来可能很奇怪,但其实相当简单。它只是提取参数的元素并将它们放回数组。如果你还是不明白,请看下面的例子:

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

注意,它在一些较老的浏览器(如IE 11)中不起作用,所以如果你想支持这些浏览器,你应该使用Babel。

其他回答

function sortArg(){
var args = Array.from(arguments); return args.sort();
}

函数sortArg () ( 瓦尔·阿格斯=阵列。 重返args sort (); ) ”,类游戏机。log (sortArg(20、1、2、目标、88、’19’、39、’d’’z’’ak’’bu’、90);

ES6使用rest参数

如果你能使用ES6,你可以使用:

其他参数

函数sortArgs(…args) { 返回参数。排序(函数(a, b){返回a - b;}); } document.body.innerHTML = sortArgs(12,4,6,8).toString();

你可以从链接中读到

rest形参语法允许我们将不确定数量的实参表示为数组。

如果你对…语法,它被称为扩散运算符,你可以在这里阅读更多。

ES6使用Array.from()

使用Array.from:

函数sortArgs() { return Array.from(arguments).sort(function (a, b) {return a - b;}); } document.body.innerHTML = sortArgs(12,4,6,8).toString();

from简单地将类数组或可迭代对象转换为数组实例。



ES5

你可以在arguments对象上使用Array的slice函数,它会把它转换成一个标准的JavaScript数组。你只需要通过Array的原型手动引用它:

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

为什么会这样?下面是ECMAScript 5文档本身的一段摘录:

注意:slice函数是有意通用的;它不要求它的this值是一个Array对象。因此,它可以转移到其他类型的对象中作为方法使用。slice函数能否成功应用于主机对象取决于实现。

因此,slice对任何具有length属性的东西都有效,而参数很方便地做到了这一点。


如果array .prototype.slice对你来说太拗口了,你可以使用数组字面量来略写它:

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

然而,我倾向于认为前一个版本更明确,所以我更喜欢它。滥用数组文字符号会让人觉得很俗气,看起来很奇怪。

下面是将参数转换为数组的几个方法的基准测试。

对我来说,对于少量的争论,最好的解决办法是:

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

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

虽然它可以像数组一样被索引,就像你在这个例子中看到的:

函数添加(){ var和= 0; (var = 0;我< arguments.length; + +) { Sum = Sum +参数[i]; } 返回总和; } console.log(添加(1、2、3);

然而,Arguments对象不是一个数组,除了长度之外没有任何其他属性。

您可以将arguments对象转换为一个数组,然后可以访问arguments对象。

有很多方法可以访问函数体中的arguments对象,包括:

你可以调用array . prototype .slice.call方法。

Array.prototype.slice.call(参数)

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

你可以使用数组文字

[] .slice.call(参数)。

function giveMeArgs (arg1, arg2)可不, var args = [].slice.call(参数); return args; 出于美观 console.log(givemeargs(1,2))

你可以使用Rest…

函数给出MeArgs(...参数){ 返回参数; } console.log(giveMeArgs(1,2))

你可以用spread[…]

function giveMeArgs()可不, var args=[…参数]; return args; 出于美观 console.log (giveMeArgs (1,2));

你可以使用Array.from()

函数giveMeArgs () ( 瓦尔·阿格斯=阵列。 重返args; ) 游戏机。log (giveMeArgs (1,2));

Lodash:

var args = _.toArray(arguments);

在行动:

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

生产:

[2,3]