【问题标题】:Removing an argument from arguments in JavaScript从 JavaScript 中的参数中删除参数
【发布时间】:2013-11-23 02:33:17
【问题描述】:

我想为函数调用添加一个可选的boolean 参数:

function test() {
  if (typeof(arguments[0]) === 'boolean') {
    // do some stuff
  }
  // rest of function
}

我希望函数的其余部分只看到arguments 数组没有可选的boolean 参数。我意识到的第一件事是arguments 数组不是数组!这似乎是一个标准的Object,属性为0、1、2等。所以我做不到:

function test() {
  if (typeof(arguments[0]) === 'boolean') {
    var optionalParameter = arguments.shift();

我收到shift() 不存在的错误。那么有没有一种简单的方法可以从 arguments 对象的开头删除参数?

【问题讨论】:

  • 只是猜测:delete arguments[0]?

标签: javascript arrays arguments javascript-objects


【解决方案1】:

arguments 不是数组,它是一个类似对象的数组。您可以通过访问Array.prototype 来调用arguments 中的数组函数,然后通过使用.apply() 传递argument 作为其执行上下文来调用它

试试

var optionalParameter = Array.prototype.shift.apply(arguments);

演示

function test() {
    var optionalParameter;
    if (typeof (arguments[0]) === 'boolean') {
        optionalParameter = Array.prototype.shift.apply(arguments);
    }
    console.log(optionalParameter, arguments)
}
test(1, 2, 3);
test(false, 1, 2, 3);

我在某些地方看到的另一个版本是

var optionalParameter = [].shift.apply(arguments);

演示

function test() {
    var optionalParameter;
    if (typeof (arguments[0]) === 'boolean') {
        optionalParameter = [].shift.apply(arguments);
    }
    console.log(optionalParameter, arguments)
}
test(1, 2, 3);
test(false, 1, 2, 3);

【讨论】:

  • 请注意,这也会影响任何命名参数,并且对作为命名参数访问时提供的最后一个参数产生特别有趣的影响。如果您有function foo(a, b, c) 并调用foo(1, 2, 3) 并执行上述转换,则bc 最终将成为3。这可能是你想要的。或者不。
  • 很惊讶这个作品!所以shift 不仅返回第一个元素,而且将传入的Object 转换为array,然后在删除第一个元素的情况下转换回Object?正是我想要的,但令人惊讶......
  • @at 实际上并非如此。 “移位”代码运行并“假装”该对象实际上是一个数组;它不执行任何转换。正因如此,这一招才有了克劳德先生所说的效果。如果您需要做这种事情,您可能应该将 arguments 转换为一个数组并从那里开始工作。
  • 如果您想保持arguments 不变并创建一个新数组,请使用切片:var newArguments = [].slice.call(arguments, 1);
  • 重要的是要理解,在 Javascript 中,函数本身就是对象,因此可以独立存在。您可以将它们从一个对象中取出并将它们放在另一个对象上。将这一点与所有数组函数按照约定仅依赖于具有length 属性的对象这一事实相结合,您就会明白为什么这个解决方案有效。
【解决方案2】:

正如 Arun 指出的那样,arguments 不是数组

你必须转换成一个数组

var optionalParameter = [].shift.apply(arguments);

【讨论】:

  • Arun 的原始答案没有替代解决方案。后来添加的
【解决方案3】:

这并不花哨,但在没有副作用的情况下删除第一个参数的最佳解决方案可能是

  for (var i=0;i<arguments.length;i++) arguments[i]=arguments[i+1];

例子:

function f(a, b, c, d) {
  for (var i=0;i<arguments.length;i++) arguments[i]=arguments[i+1];
  console.log(a,b,c,d); 
}
f(1,2,3,4); // logs 2,3,4,undefined

【讨论】:

  • 代码运行后,arguments.length === 4。我认为您应该通过在 for 循环之后将其设置为 arguments.length-1 来完成这项工作。
猜你喜欢
  • 2016-07-24
  • 2012-01-31
  • 1970-01-01
  • 2014-10-25
  • 2018-11-20
  • 1970-01-01
相关资源
最近更新 更多