【问题标题】:Trying to understand concept of arguments array in Javascript试图理解 Javascript 中参数数组的概念
【发布时间】:2015-12-16 22:09:21
【问题描述】:

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

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

(我不确定这是否是解释参数的好例子,但我也试图理解 apply() 在这里的工作原理......)

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

【问题讨论】:

    标签: javascript callback


    【解决方案1】:

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

    1. 函数调用中this 指针的值。
    2. 当参数源是数组时要传递给函数的一组参数。

    如果事先知道要传递给函数的参数数量,通常会使用.call(),如果事先不知道参数的数量,因此通常会使用.apply(),因此参数在数组中或可以放入数组中。

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

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

    所以,如果你打电话:

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

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

    这是一个有效的 sn-p 示例:

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

    【讨论】:

      【解决方案2】:

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

      考虑以下 2 个 sn-ps 之间的区别:

      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对象只是类数组,不包含这个方法。

      【讨论】:

      • 但是如果我将其设置为空白数组,为什么不能传入其他参数?
      • @Danny 因为参数对象中可能有更多参数,这些参数将包含在切片数组中。空数组永远不会包含它们。
      猜你喜欢
      • 1970-01-01
      • 2022-01-22
      • 2019-02-10
      • 1970-01-01
      • 2013-10-04
      • 1970-01-01
      • 1970-01-01
      • 2020-03-21
      • 2014-10-07
      相关资源
      最近更新 更多