如何从“论据”中切出一块


79

您所知道的arguments是一个特殊的对象,其中包含传递给函数的所有参数。

只要它不是数组,就不能使用arguments.slice(1)

因此,问题-如何从第一个元素中切出所有元素arguments

UPD

似乎没有办法将其转换为数组

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

如果有人发布了另一个解决方案,那就更好了,如果不是这样的话-我将检查第一个解决方案,上面的行作为答案。


+ zerkms确实有比arguments将其转换为数组等更好的方法。请在下面查看我的答案。
UmurKaragöz17年

Answers:


18

实际上不需要使用数组函数进行干预。

使用rest参数语法 ...rest更简洁,更方便。

function argumentTest(first, ...rest) {
  console.log("First arg:" + first);

  // loop through the rest of the parameters
  for (let arg of rest) {
    console.log("- " + arg);
  }
}

// call your function with any number of arguments
argumentTest("first arg", "#2", "more arguments", "this is not an argument but a contradiction");

...休息


是的,我同意这几天比较方便。我投票给您,但我不会追溯更改5年检查的答案。
zerkms

2
现在又过了一年,我认为是时候换用新的ES标准了:-)
zerkms

一年的答案得到+15分时的感觉:-D
zerkms 18-10-11

133

问:如何切片除第一个元素以外的所有内容arguments

以下将返回一个数组,其中包含除第一个参数外的所有参数:

var slicedArgs = Array.prototype.slice.call(arguments, 1);

您不必arguments首先转换为数组,只需一步即可完成所有操作。


我相信这是不利的。如果只有一个附加参数(第一个参数除外),则不会返回任何内容。
Trevor 2014年

@Trevor-不,它返回一个数组,其中一个元素是第二个参数。(为什么不返回任何内容?)
nnnnnn 2014年

4
此处的建议指出,不应在参数上使用切片,因为这会阻止JavaScript引擎优化。
林纳森·林

1
更详细的解释可以发现这里
大卫大通

4
@David-“详细”链接仍然说不要使用.slice()on arguments,但是给出的唯一原因是它阻止了JS引擎对该功能的优化。因此,它并不是失败,而是可能会更慢。我不会写代码来满足当今JS引擎的优化需求,而不是明天的引擎可能已经解决了优化问题时,无论如何在大多数情况下用户都不会感觉到差异案件。最好先编写清晰且易于维护的代码,然后仅在出现可衡量的性能问题时再进行优化。
nnnnnn

11

您可以通过按顺序遍历arguments对象来“切片而不切片”:

function fun() {
  var args = [];

  for (var i = 1; i < arguments.length; i++) {
    args.push(arguments[i]);
  }

  return args;
}

fun(1, 2, 3, 4, 5); //=> [2, 3, 4, 5]

2
是啊,它的工作,但没有任何意义的情况下,我们有一个.slice();-)
zerkms

当然,它更易于使用Array.prototype.slice,但是您的问题是是否还有另一种方法。
保罗·罗萨尼亚

是的,谢谢你;for
zerkms 2012年

哈哈,我希望我不要陈词滥调。有时,这是关于SO的有用信息!
Paul Rosania'3

3
+1这似乎是V8的唯一正确解决方案。在此处查看优化基准测试:jsperf.com/leaky-args
Tom Auger

11

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions/arguments

您不应切入参数,因为它会阻止JavaScript引擎(例如V8)中的优化。而是尝试通过遍历arguments对象构造一个新数组。

因此,Paul Rosiana的答案是正确的


4
可能是这样。但是我看不到优化引擎如何无法处理接受的答案的一线而以他们希望的任何方式对其进行优化。从长远来看,如果我们开始为当天的优化程序编写代码,那么从长远来看总是很麻烦的。
2015年

2
“切片”不会改变。它从原始数组返回元素的浅表副本。将原始数组的元素复制到返回的数组中。因此,我无法理解手动复制到新数组和切片之间的区别。
Maxim 2015年

截至2018年,警告不再存在。我猜我们应该很安全。
GBF_Gabriel

9

这可以是一种方法:

var args = Array.from(arguments).slice(1);

这些天根本没有必要:function foo(...args)
zerkms '17

@zerkms由于性能原因,我将拒绝您的建议,但是我的测试显示剩余参数是最快的解决方案!gist.github.com/18d590d12aef1e90d2ed262f4fab0c96
科迪·艾伦·泰勒

@CodyAllanTaylor的实现得到改善。除非您有真正非常重要的理由不这样做,否则我将坚持使用可读性更高的语法
zerkms

0

您可以使用方法 [].slice.call(arguments, 1)

[] .slice将返回您的slice函数对象,您可以将其称为arguments1作为参数


在发布答案之前,您对发布的答案进行了任何检查?相同的答案(甚至更好一点,因为它没有分配一次性数组)已经发布并进行了检查。
zerkms

0

您可以在函数内使用... rest来分隔第一个参数和其余参数:

function foo(arr) {
  const [first, ...rest] = arguments;
  console.log(`first = ${first}`);
  console.log(`rest = ${rest}`);
}
//Then calling the function with 3 arguments:
foo(1,2,3)


耶,未来终于到了:-D
zerkms
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.