我有一个forEach函数被定义为对数组中的所有项做“某事”:
function forEach(array, action) {
for (var i = 0; i < array.length; i++)
action(array[i]);
}
var numbers = [1, 2, 3, 4, 5], sum = 0;
所以我能做到:
forEach(numbers, console.log);
它将打印出所有数字,因为'console.log(array [i])'将数字打印到控制台。 我得到那个部分。
这就是我被困的地方:如果我将下面的函数传递给action参数的位置,而不是'console.log',那么函数在什么时候知道每个元素?
forEach(numbers, function(number) {
sum += number;
});
console.log(sum);
// 15
如何评估?如果我将console.log传递给最后一个问题,它仍然必须被评估为'console.log(array [i])',并且传入的参数旁边带有'(array [i])'代码,那么是不是因为该函数是参数而被应用于整个函数?如下:
function(number) { sum += number; }(array[i])
答案 0 :(得分:1)
函数在什么时候知道每个元素
在任何时候(就像你传递console.log
时一样)。
forEach
函数在此行上调用它:
action(array[i]);
此时,它只知道数组中的单个值,因为这是传递给它的全部内容。
(它也知道sum
变量,因为它的定义范围比函数更广。)
答案 1 :(得分:1)
如何评估?
它会创建一个新范围(包含array
,action
和i
个变量),并将该函数分配给action
变量 - &#39; sa 函数调用。
您
var sum = 0;
forEach([1, 2, 3, 4, 5], function(number) {
sum += number;
});
与
相同var sum = 0;
{ // let's assume block scope here
var array = [1, 2, 3, 4, 5],
action = function(number) {
sum += number;
},
i;
for (i = 0; i < array.length; i++)
action(array[i]);
}
如果我将
console.log
传递给最后一个问题并且仍然需要进行评估,那么由于该函数是参数,那么它是否也适用于整个函数?
是的,确切地说。您正在传递一个函数对象 - 无论是通过引用console.log
变量还是通过动态创建它(使用函数表达式)获得该函数对forEach
都不重要。它只会在action(…)
处执行 - 其中为您的函数的array[i]
参数传递number
值。
答案 2 :(得分:0)
在JavaScript中,功能是一等公民。这意味着它们可以被视为变量,就像字符串,数字等一样。
当你这样做时:
forEach(numbers, function(number) {
sum += number;
});
您正在传递forEach
匿名功能。它不是在变量中的函数,而是在运行中创建的。在forEach
函数中,action
将包含您的匿名函数。
在for for
循环中,为每个元素调用action
函数。
答案 3 :(得分:0)
这是解决问题的方法:
function forEach(array, action) {
for (var i = 0; i < array.length; i++){
if(typeof action == 'function'){
action(array[i]);
}else{
var slices = action.match(/(.+)\.([a-zA-Z0-9]+)/);
var object = eval(slices[1]);
var action = slices[2];
object[action](array[i]);
}
}
}
我已经用两种方案对它进行了测试,它就像魔法一样