对Resig Curry示例和“参数”感到困惑对象

Confused About Resig Curry Example And "arguments" Object

本文关键字:对象 参数 Curry Resig      更新时间:2023-09-26

在本文中,John Resig讨论了curry的代码片段:

Function.prototype.curry = function() {
    var fn = this, args = Array.prototype.slice.call(arguments);
    return function() {
      return fn.apply(this, args.concat(
        Array.prototype.slice.call(arguments)));
    };
  };

我对表达Array.prototype.slice.call(arguments)感到困惑。

  1. 这里的"参数"是"this"参数数组的slice()方法,但"slice()"需要一个参数本身,所以我认为你需要做一些像Array.prototype.slice.call(arguments, <someIndex>)。我不明白代码是怎么工作的。

  2. 根据文档上的"参数","参数"实际上不是一个数组,而只是一个类似对象的数组。我们如何在它上面调用"slice()"?如果我输入代码console.log(arguments.slice()),我得到一个错误,说对象没有切片方法。

这是怎么回事?

第一个问题的答案:

如果在一个没有参数的数组上调用slice,它将返回该数组的一个副本。Array.prototype.slice.call(arguments)做同样的事情,但是在arguments对象上操作,返回一个数组。

第二个问题的答案:

我们可以在arguments上调用slice,因为它是一个"泛型"方法(见这里的注释)。当您将arguments对象作为this传递时,slice将把它视为一个数组。由于arguments是一个包含length属性的类数组对象,因此它可以正常工作。

.slice()是可选参数。如果没有,则该函数只返回原始数组(或类数组对象)的副本。

.slice()函数只关心this对象上是否存在"length"属性。因此,因为"参数"确实有一个"长度"属性,.slice()很高兴。