2 回答
![?](http://img1.sycdn.imooc.com/5458477f0001cabd02200220-100-100.jpg)
TA贡献1824条经验 获得超5个赞
根据我的理解,您对匿名/ lambda 函数如何对无限数量的参数进行操作感到困惑。
让我们编写我们自己的过滤器函数来看看它是如何工作的。首先,我们需要两件事,一个对象/值数组,以及将这些值映射到 true(应该在结果数组中)或 false(不应该在结果数组中)的某种方法。然后我们需要做的就是选择评估的值以尝试并返回它们。
// Define array
var words = ['spray', 'limit', 'elite', 'exuberant', 'destruction', 'present'];
// Define filter
function hasAnE(word) {
return word.includes('e');
}
// Examples
hasAnE(words[0]); // false
hasAnE(words[1]); // false
hasAnE(words[2]); // true
// Create an array for our results
filteredWords = [];
// Go through our words array and check for matches
for (var index = 0; index < words.length; index ++) {
word = words[index];
// Map each element to true / false
filterResult = hasAnE(word);
// If it matches the filter, add it to the results
if (filterResult) {
filteredWords.push(word);
}
}
console.log(filteredWords); // [ 'elite', 'exuberant', 'destruction', 'present' ]
好的,所以我们可以自己构建这个过滤器功能,但是我们如何做到words.filter(hasAnE)呢?首先,您需要了解的是,在 JavaScript 中,您可以像传递变量一样传递函数本身。这意味着我们可以编写一个将另一个函数作为参数的函数(传递的函数称为“回调”)。
function filterWords(wordsArray, filter) {
filteredWords = [];
for (var index = 0; index < wordsArray.length; index ++) {
word = wordsArray[index];
// Map each element to true / false
filterResult = filter(word);
// If it matches the filter, add it to the results
if (filterResult) {
filteredWords.push(word);
}
}
return filteredWords;
}
console.log(filterWords(words, hasAnE)); // [ 'elite', 'exuberant', 'destruction', 'present' ]
请注意,我们得到了与之前相同的结果。JavaScript 不仅允许我们将过滤器作为输入参数传递,而且还可以无缝调用它。但是我们如何将过滤器直接应用到 words 数组本身呢?这是原型派上用场的地方,因为它允许我更改现有类的“基本”代码。例如,Array.prototype让我可以访问 Array 类(我们的 words 数组就是其中之一)的所有默认字段和方法。因此,利用我们对函数可以存储为变量的知识,我们可以这样做:
function filterWordsPrototype(filter) {
filteredWords = [];
for (var index = 0; index < this.length; index ++) {
word = this[index];
// Map each element to true / false
filterResult = filter(word);
// If it matches the filter, add it to the results
if (filterResult) {
filteredWords.push(word);
}
}
return filteredWords;
}
Array.prototype.filterWords = filterWordsPrototype;
console.log(words.filterWords(hasAnE)); // [ 'elite', 'exuberant', 'destruction', 'present' ]
这里没有魔法。我们的最终words.filterWords(hasAnE)看起来非常接近原始words.filter(someFunction)注意我如何摆脱数组参数并将对数组的所有引用this改为。那是因为我将该函数设置为数组本身(以及所有数组)的方法,所以this现在指的是我正在调用该函数的数组。
现在,实际的实现当然比这更有效、更安全、更详细,但我希望我已经回答了你关于幕后大致发生的事情的问题。
![?](http://img1.sycdn.imooc.com/54584c910001b8d902200220-100-100.jpg)
TA贡献1785条经验 获得超4个赞
正如丹尼尔在评论中指出的那样,您的函数是一个回调函数(因为不要调用 use 我们稍后会调用您)。
在引擎盖下,数组过滤器函数是这样实现的:
Array.prototype.filter = function (callback) {
const goodValues = []
for (let i = 0; i < this.length; i++) {
if (callback(this[i])) { // your callback is used here
goodValues.push(this[i])
}
}
return goodValues
}
它的要点是您提供一个函数(函数也是对象)作为参数。然后 filter 的过滤器实现将使用您的函数来确定它是否应该保留一个值或将其丢弃。
在Array.prototype你每次创建新阵列只是手段[],将有filter功能。尽管强烈讨论,您也可以将自己的函数添加到数组中。有时,dump如果您链接许多地图和过滤器,我会得到一个帮助来理解中间值。
添加回答
举报