3

Eloquent Javascript 包含以下代码示例:

function map(func, array) {
  var result = [];
  forEach(array, function (element) {
    result.push(func(element));
  });
  return result;
}

function asArray(quasiArray, start) {
  var result = [];
  for (var i = (start || 0); i < quasiArray.length; i++)
    result.push(quasiArray[i]);
  return result;
}

function partial(func) {
  var fixedArgs = asArray(arguments, 1);
  return function(){
    return func.apply(null, fixedArgs.concat(asArray(arguments)));
  };
}

function square(x) {return x * x;}

console.log(map(partial(map, square), [[10, 100], [12, 16], [0, 1]]));

我理解mapand asArray,但partial让我感到困惑。上面的调用返回

[[100, 10000], [144, 256], [0, 1]]

但我不明白怎么做。以下是我的问题:

1)在partial定义arguments中,第一行的arguments变量和最后一行的变量是一样的吗?如果不是,每个参数对象的来源是什么?

2)当函数调用发生在上面最后的代码行时,我的理解是fixedArgs绑定到[square](即包含square函数的数组)。然后concat用二维数组调用它。这些绑定产生了许多问题,而不是正确的答案,因此它们不可能是正确的。调用时部分绑定的变量如何?

4

3 回答 3

3

1)在部分定义中,第一行的arguments变量是否与最后一行的arguments变量相同?如果不是,每个参数对象的来源是什么?

不,不是arguments是基于当前的功能。第一行是提供给partial自身的参数,第三行是应用于函数的参数。

引用规范:

当控制进入函数代码的执行上下文时,会创建一个参数对象

我们在这里所做的是应用最初提供的参数以及稍后提供的参数。我们将最初给出的参数与调用期间给出的参数连接起来以创建一个部分。

2)当函数调用发生在上面最后的代码行时,我的理解是fixedArgs绑定到[map](即包含map函数的数组)。然后用二维数组调用 concat 。这些绑定产生了许多问题,而不是正确的答案,因此它们不可能是正确的。调用时部分绑定的变量如何?

最后一行的代码在做什么:

  • partial(map, square)- 创建一个map用作square第一个参数的函数,这基本上创建了一个获取数组并将其平方的函数。

  • map(result, [[10, 100], [12, 16], [0, 1]])- 这再次执行映射。这次我们将数组中的每个元素映射到上面声明的函数。数组中的元素本身就是数组,我们上面定义的函数接受一个数组并对其所有元素求平方,所以它所做的就是对内部数组的所有元素求平方。

所以我们得到期望得到[100,1000],...

于 2013-11-01T23:17:11.570 回答
3

1)不,它们是不同的。arguments第一行包含partial. arguments最后一行包含partial返回的匿名函数的参数。

2)fixedArgs包含数组[square]。由于它是从 创建的asArray(arguments, 1),因此它会跳过参数 0,即map,并包含所有剩余的参数。

于 2013-11-01T23:17:25.370 回答
2

1)arguments是一个特殊的 JavaScript 变量。它是传递给该函数的所有参数的数组。所以这arguments是两个不同的变量:第一个是传递给的参数partial,第二个是传递给返回函数的参数。

2) 该partial函数返回一个新函数,该函数在被调用mapsquare作为唯一参数调用。外部map调用处理给定(二维)数组中的所有数组:map处理每个部分,partial(map, square)准备一个对传递数组中的所有值求平方的函数。

编辑:我肯定打字太慢了。

于 2013-11-01T23:17:40.293 回答