试图在Javascript中理解参数数组的概念

时间:2015-12-16 22:09:22

标签: javascript callback

我知道参数在每个函数中都是类似数组的对象,但我不确定为什么需要它以及我们如何使用它?下面是一个让我困惑的例子......

那么为什么我们不能简单地把var args = [],而是在参数上使用slice?

(我不确定它是否是一个很好的例子来解释arugments,但我也试图了解apply()在这里是如何工作的......)

_.delay = function(func, wait) {
    var args = slice.call(arguments, 2);
    return setTimeout(function(){
      return func.apply(null, args);
    }, wait);
  };

2 个答案:

答案 0 :(得分:1)

此代码将在前2个之后获取任何参数,并将它们放入新数组中。如果将其设置为空数组,除了命名数据之外,您将不会传递任何可能已传递的参数。

考虑以下两个片段之间的区别:

var slice = Array.prototype.slice;

function test(a, b) {
  var args = slice.call(arguments, 2);
  console.log(args);
}
test(1, 2, 3, 4);

控制台输出:

  

[3, 4]

function test(a, b) {
  var args = [];
  console.log(args);
}
test(1, 2, 3, 4);

控制台输出:

  

[]

有必要在arguments数组上调用slice,因为arguments对象只是类似数组,并且不包含此方法。

答案 1 :(得分:1)

.apply()允许您在指定两个不同的东西时调用函数:

  1. 函数调用中this指针的值。
  2. 当参数源是数组时传递给函数的一组参数。
  3. 如果事先知道传递给函数的参数数量,通常会使用.call(),并且当事先不知道参数数量时通常会使用.apply()因此参数是在数组中或可以放入数组。

    据推测,您显示的代码示例中的slice()Array.prototype.slice,因此代码示例在前两个之后抓取参数集并将它们放入自己的数组中,以便它们可以传递原来的功能。

    Javascript中的arguments对象是“类似于数组”。它具有.length属性,并且像数组一样零索引,但它没有任何数组方法。因此,如果要在.slice()上使用数组方法将某些元素复制到新数组,则必须从数组原型中手动指定数组方法,而不是直接在参数上使用.slice()对象

    所以,如果你打电话:

    function myFunc(a, b, c, d) {
       // four arguments present here
    }
    
    _.delay(myFunc, 100, 1, 2, 3, 4);
    

    _.delay()的内部工作方式会跳过传递给它的前两个参数(因为它们直接在_.delay()中使用,只获取剩余的最后四个参数,然后将它们传递给回调函数使用.apply()

    这是一个有效的代码示例:

    var _ = {};
    var slice = Array.prototype.slice;
    
    _.delay = function(func, wait) {
        var args = slice.call(arguments, 2);
        return setTimeout(function(){
            func.apply(null, args);
        }, wait);
    };
    
    function myFunc() {
       log("number of arguments passed to myFunc(): " + arguments.length);
       log(JSON.stringify(slice.call(arguments)));
    }
    
    _.delay(myFunc, 500, 1, 2, 3, 4)
    
    function log(x) {
        var div = document.createElement("div");
        div.innerHTML = x;
        document.body.appendChild(div);
    }