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]]));
我理解map
和asArray
,但partial
让我感到困惑。以上调用返回
[[100, 10000], [144, 256], [0, 1]]
但我不明白怎么做。以下是我的问题:
1)在partial
定义中,第一行中的arguments
变量与最后一行中的arguments
变量相同吗?如果没有,那么每个参数对象的来源是什么?
2)当函数调用发生在上面的最后一行代码行上时,我的理解是fixedArgs
绑定到[square]
(即包含square函数的数组)。然后使用二维数组在其上调用concat
。这些绑定产生了许多问题,而不是正确的答案,因此它们不是正确的。如果变量在被调用时是如何部分绑定的?
答案 0 :(得分:3)
1)在部分定义中,第一行中的arguments变量是否与最后一行中的arguments变量相同?如果没有,那么每个参数对象的来源是什么?
不,不是。 arguments
基于current function。在第一行中,它是提供给partial
本身的参数,在第三行中,它是应用于函数的参数。
引用规范:
当控件进入功能代码的执行上下文时,会创建一个arguments对象
我们在这里做的是将最初提供的参数另外应用于稍后提供的参数。我们将最初给出的参数与调用期间给出的参数进行汇总以创建部分参数。
2)当函数调用发生在上面的最后一行代码行上时,我的理解是fixedArgs绑定到[map](即包含map函数的数组)。然后使用二维数组调用concat。这些绑定产生了许多问题,而不是正确的答案,因此它们不是正确的。如果变量在被调用时是如何部分绑定的?
最后一行的代码是:
partial(map, square)
- 创建一个使用map
作为第一个参数的square
函数,这基本上创建了一个获取数组并对其进行平方的函数。
map(result, [[10, 100], [12, 16], [0, 1]])
- 这会再次执行映射。这次我们将数组中的每个元素映射到上面声明的函数。数组中的元素本身就是数组,我们上面定义的函数采用数组并对其所有元素进行正方形,因此它所做的就是对内部数组的所有元素进行平方。
所以我们期望获得[100,1000],...
答案 1 :(得分:3)
1)不,他们是不同的。第一行中的arguments
包含partial
的参数。最后一行中的arguments
包含partial
返回的匿名函数的参数。
2)fixedArgs
包含数组[square]
。由于它是从asArray(arguments, 1)
创建的,因此它会跳过参数0,即map
,并包含所有剩余的参数。
答案 2 :(得分:2)
1)arguments
是一个特殊的JavaScript变量。它是传递给该函数的所有参数的数组。所以那些arguments
是两个不同的变量:第一个引用传递给partial
的参数,第二个引用传递给返回函数的参数。
2)partial
函数返回一个新函数,在调用时,调用map
并将square
作为唯一参数。外部map
调用处理给定(二维)数组中的所有数组:map
处理每个部分,partial(map, square)
准备一个函数,该函数对传递的数组中的所有值进行平方。
编辑:我打算打字太慢了。