2017-11-25 162 views
3

我试图得到callback functions的挂钩,但我遇到了一些我不完全了解的东西。.filter()如何使回调函数调用另一个函数?

这段代码在下面的例子中使用时效果很好。

zombieCreatures = creatures.filter(filterCreatures); 

不幸的是,这个代码块在同一个例子中不起作用。

zombieCreatures = creatures.filter(function(v) { 
    filterCreatures(v); 
}); 

对我来说,他们看起来像相同的指令,但显然我不正确。有什么不同? .filter()之内是否有可能使回调函数调用另一个函数?

'use strict'; 
 

 
var creatures = [], zombieCreatures = []; 
 

 
var filterCreatures; 
 

 
creatures = [ 
 
    {species: 'Zombie', hitPoints: 90}, 
 
    {species: 'Orc', hitPoints: 40}, 
 
    {species: 'Skeleton', hitPoints: 15}, 
 
    {species: 'Zombie', hitPoints: 85} 
 
]; 
 
\t 
 
filterCreatures = function(v) { 
 
    return v.species === 'Zombie'; 
 
} 
 
\t 
 
zombieCreatures = creatures.filter(function(v) { 
 
    filterCreatures(v); 
 
}); 
 

 
console.log(zombieCreatures);

回答

4

是的,你当然可以叫filter回调内部的任何其他功能。

你唯一缺少的是回调需要返回的值。您的回拨没有return声明。它调用filterCreatures()函数,但它会丢弃该函数返回的值,默认返回undefined

比较与您的代码的原始版本:

creatures.filter(filterCreatures); 

在这段代码,filter()直接调用filterCreatures功能,然后使用它的返回值来决定是否要包括的元素。您在代码中没有明确地看到这一点,但filter()正在寻找该返回值。

下面是一个练习,以帮助澄清这一点。取出您的破解代码并将内联过滤器回调移出到指定函数。我们将其称为filterCreaturesWrapper。因此,而不是这样的:

filterCreatures = function(v) { 
    return v.species === 'Zombie'; 
} 

zombieCreatures = creatures.filter(function(v) { 
    filterCreatures(v); 
}); 

,我们有这样的:

filterCreatures = function(v) { 
    return v.species === 'Zombie'; 
} 

filterCreaturesWrapper = function(v) { 
    filterCreatures(v); 
} 

zombieCreatures = creatures.filter(filterCreaturesWrapper); 

如果你学习,你会看到它像以前一样是完全相同的代码,我们刚刚搬到这附近有一座小。 filterCreaturesWrapper与在.filter()调用中内联的功能相同。现在问题应该跳出来,我们:filterCreatures有一个return声明和filterCreaturesWrapper没有。

再回到原来的断码,这是因为如果我们写:

zombieCreatures = creatures.filter(function(v) { 
    filterCreatures(v); 
    return undefined; // .filter treats this as 'false' 
}); 

因此,只要在你的回调添加return和它的作品:

'use strict'; 
 

 
var creatures = [], zombieCreatures = []; 
 

 
var filterCreatures; 
 

 
creatures = [ 
 
    {species: 'Zombie', hitPoints: 90}, 
 
    {species: 'Orc', hitPoints: 40}, 
 
    {species: 'Skeleton', hitPoints: 15}, 
 
    {species: 'Zombie', hitPoints: 85} 
 
]; 
 
\t 
 
filterCreatures = function(v) { 
 
    return v.species === 'Zombie'; 
 
} 
 
\t 
 
zombieCreatures = creatures.filter(function(v) { 
 
    return filterCreatures(v); // <-- added "return" 
 
}); 
 

 
console.log(zombieCreatures);

并非所有的语言都是这样的。例如,Ruby无论是否明确说明return,都会返回方法(函数)中的最后一个表达式。所以,如果你正在编写Ruby代码(假设所有其他位都转换为Ruby),那么你的代码就可以工作了!

+0

非常感谢你,我拉着我的头发!我从来没有想过使用'return'。我要阅读'return'。我把那一个拧得比我想要承认的要多。 – DR01D

1

filter将调用它为数组中的每个项目提供的函数。它会检查每个项目的该函数的返回值,如果返回值为真,它会将该项目添加到新数组中。

换句话说,它返回一个回调函数返回一个真值的所有项的数组。

在第一个示例中,您直接传递filterCreatures函数,当生物为僵尸时返回true

在第二个例子中,你传递的另一个功能和呼叫filterCreatures内部,但不返回任何东西的意思传递给筛选每一个项目,这是falsy没有东西回报过滤的undefined回调。

对于它的工作,你必须返回调用filterCreatures的结果:

zombieCreatures = creatures.filter(function(v) { 
    return filterCreatures(v); 
}); 

话虽这么说,周围filterCreatures附加功能没有太多使用时filterCreatures本身并没有你所需要的一切。