40

让我们看一下这段代码:

var mainFunction = function() {
  altFunction.apply(null, arguments);
}

传递给的参数mainFunction是动态的——它们可以是 4 或 10,没关系。但是,我必须将它们传递给altFunction并且我必须在参数列表中添加一个 EXTRA 参数。

我试过这个:

var mainFunction = function() {
  var mainArguments = arguments;
  mainArguments[mainArguments.length] = 'extra data'; // not +1 since length returns "human" count.

  altFunction.apply(null, mainArguments);
}

但这似乎不起作用。我怎样才能做到这一点?

4

11 回答 11

64

采用Array.prototype.push

[].push.call(arguments, "new value");

没有必要对arguments对象进行浅层克隆,因为它和它.length是可变的。

(function() {
    console.log(arguments[arguments.length - 1]); // foo

    [].push.call(arguments, "bar");

    console.log(arguments[arguments.length - 1]); // bar
})("foo");

从 ECMAScript 5、10.6 参数对象

  1. 调用[[DefineOwnProperty]]obj 传递的内部方法"length"、Property Descriptor{[[Value]]: len, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true}和 false 作为参数。

所以你可以看到它.length是可写的,所以它会用 Array 方法更新。

于 2012-11-28T17:33:11.670 回答
34

arguments不是纯数组。您需要从中制作一个普通数组:

var mainArguments = Array.prototype.slice.call(arguments);
mainArguments.push("extra data");
于 2012-11-28T17:32:19.360 回答
4

arguments对象不是数组;它就像一个数组,但它是不同的。但是,您可以将其转换为数组:

var mainArguments = [].slice.call(arguments, 0);

然后你可以将另一个值推到最后:

mainArguments.push("whatever");
于 2012-11-28T17:32:11.150 回答
2

2016 年更新:您必须在添加元素之前将参数转换为数组。除了很多帖子中提到的 slice 方法:

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

您还可以使用 Array.from() 方法或扩展运算符将参数转换为真正的数组:

var args = Array.from(arguments);

或者

var args = [...arguments];

您的javascript引擎可能未优化上述内容,MDN已建议以下可能进行优化:

var args = (arguments.length === 1 ? [arguments[0]] : Array.apply(null, arguments));

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments

于 2016-06-30T16:33:00.837 回答
1
var mainFunction = function() {
    var args = [].slice.call( arguments ); //Convert to array
    args.push( "extra data");
    return altFunction.apply( this, args );
}
于 2012-11-28T17:32:18.880 回答
1

arguments数组”不是数组(根据 Crockford 的说法,它是 JavaScript 中的一个设计错误),所以你不能这样做。但是,您可以将其转换为数组:

var mainFunction = function() {
  var mainArguments = Array.prototype.slice.call(arguments);
  mainArguments.push('extra data');

  altFunction.apply(null, mainArguments);
}
于 2012-11-28T17:33:31.063 回答
0

一个用于添加其他参数并返回新数组的衬垫:

[].slice.call(arguments).concat(['new value']));
于 2013-08-03T17:45:01.693 回答
0
//
//    var
//        altFn  = function () {}, 
//        mainFn = prefilled( altFn  /* ...params */ );
//
//    mainFn(  /* ...params */  );
//  
//        
function prefilled ( fn /* ...params */ ) { 
     return ( function ( args1 ) { 

          var orfn = this;

          return function () { 

              return orfn.apply( this, args1.concat( cslc( arguments ) ) );

          };

     } ).call( fn, cslc( arguments, 1 ) );
}

// helper fn
function cslc( args, i, j ) { 
   return Array.prototype.slice.call( args, i, j );
}


// example

var
    f1 = function () { console.log( cslc( arguments ) ); }, 
    F1 = prefilled( f1, 98, 99, 100 );

F1( 'a', 'b', 'c' );

//
//   logs: [98, 99, 100, "a", "b", "c"]
//
//
于 2013-08-12T22:56:09.067 回答
0

在这种情况下,使用它可能会更舒适,call()而不是apply()

function first(parameter1, parameter2) {

  var parameter3 = "123";

  secondFunction.call(
    this,
    parameter1,
    parameter2,
    parameter3);
},
于 2017-03-29T05:14:35.200 回答
0

var myABC = '12321'; someFunction(result, error, myCallback.bind(this, myABC));

参考:https ://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind

于 2017-07-15T23:37:27.183 回答
0

对于那些像我一样正在寻找一种方法来添加可选参数并且可能不是唯一省略的参数(myFunc = function(reqiured,optional_1,optional_2,targetOptional)使用 like 调用myFunc(justThisOne))的人,可以按如下方式完成:

// first we make sure arguments is long enough
// argumentPosition is supposed to be 1,2,3... (4 in the example above)
while(arguments.length < argumentPosition)
    [].push.call(arguments,undefined);
// next we assign it
arguments[argumentPosition-1] = arguments[argumentPosition-1] || defaultValue;
于 2018-03-17T18:07:24.720 回答