如何在 Javascript .filter() 方法中将额外参数传递给回调函数?
Posted
技术标签:
【中文标题】如何在 Javascript .filter() 方法中将额外参数传递给回调函数?【英文标题】:How do I pass an extra parameter to the callback function in Javascript .filter() method? 【发布时间】:2011-12-07 05:41:57 【问题描述】:我想将数组中的每个字符串与给定的字符串进行比较。我目前的实现是:
function startsWith(element)
return element.indexOf(wordToCompare) === 0;
addressBook.filter(startsWith);
这个简单的函数有效,但只是因为现在 wordToCompare 被设置为全局变量,但我当然想避免这种情况并将其作为参数传递。我的问题是我不确定如何定义 startsWith() 所以它接受一个额外的参数,因为我真的不明白它采用的默认参数是如何传递的。我已经尝试了所有我能想到的不同方法,但都没有奏效。
如果您还可以解释传递给“内置”回调函数的参数(对不起,我不知道更好的术语)是如何工作的,那就太好了
【问题讨论】:
Pass an extra argument to a callback function的可能重复 【参考方案1】:function startsWith(element, wordToCompare)
return element.indexOf(wordToCompare) === 0;
// ...
var word = "SOMETHING";
addressBook.filter(function(element)
return startsWith(element, word);
);
【讨论】:
【参考方案2】:使startsWith
接受要比较的单词并返回一个函数,然后将其用作过滤器/回调函数:
function startsWith(wordToCompare)
return function(element)
return element.indexOf(wordToCompare) === 0;
addressBook.filter(startsWith(wordToCompare));
另一种选择是使用Function.prototype.bind
[MDN](仅在支持 ECMAScript 5 的浏览器中可用,请点击旧版浏览器的 shim 链接)并“修复”第一个参数:
function startsWith(wordToCompare, element)
return element.indexOf(wordToCompare) === 0;
addressBook.filter(startsWith.bind(this, wordToCompare));
我不太明白它采用的默认参数是如何传递的
没有什么特别之处。在某些时候,filter
只是调用回调并传递数组的当前元素。所以它是一个调用另一个函数的函数,在这种情况下是你作为参数传递的回调。
下面是一个类似函数的例子:
function filter(array, callback)
var result = [];
for(var i = 0, l = array.length; i < l; i++)
if(callback(array[i])) // here callback is called with the current element
result.push(array[i]);
return result;
【讨论】:
好的,我明白了。我试图将参数直接传递给回调函数......我真的需要处理我的 javascript。谢谢菲利克斯,你的回答很有帮助 传递额外的参数怎么样?我尝试传递一系列参数,但似乎失败了 @geotheory:他们呢?你可以像其他函数一样传递多个参数。 bind(this) after function name 以及 filter() 链接帮助我在函数内部使用 .this。谢谢。 在第一个 sn-p 中,element
来自哪里,在 startsWith
函数中?【参考方案3】:
filter的第二个参数会在回调中设置this。
arr.filter(callback[, thisArg])
所以你可以这样做:
function startsWith(element)
return element.indexOf(this) === 0;
addressBook.filter(startsWith, wordToCompare);
【讨论】:
我发现这是最好的答案。 所以现在新数组将被分配给 wordToCompare 对象,对吧?以后如何使用 wordToCompare 对象访问新数组? 最佳答案。非常适合过滤和查找。并且两者都符合 WC3 文档:thisValue - 可选。要传递给函数以用作其“this”值的值。如果此参数为空,则值“undefined”将作为其“this”值传递 @TarekEldeeb 只需传递您制作的对象one: 'haha', two:'hoho'
这是一个很好的例子,说明在复杂性、复杂程度与简单程度方面的答案之间存在巨大差异【参考方案4】:
您可以在过滤器中使用箭头函数,如下所示:
result = addressBook.filter(element => element.indexOf(wordToCompare) === 0);
Arrow functions on MDN
与函数表达式相比,箭头函数表达式的语法更短,并且在词法上绑定 this 值(不绑定自己的 this、arguments、super 或 new.target)。箭头函数始终是匿名的。这些函数表达式最适合非方法函数,它们不能用作构造函数。
【讨论】:
注:IE 不支持【参考方案5】:基于oddRaven 的回答 和 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
我做了 2 种不同的方式。 1)使用函数方式。 2)使用内联方式。
//Here is sample codes :
var templateList = [
name: "name1", index: 1, dimension: 1 ,
name: "name2", index: 2, dimension: 1 ,
name: "name3", index: 3, dimension: 2 ];
//Method 1) using function :
function getDimension1(obj)
if (obj.dimension === 1) // This is hardcoded .
return true;
else return false;
var tl = templateList.filter(getDimension1); // it will return 2 results. 1st and 2nd objects.
console.log(tl) ;
//Method 2) using inline way
var tl3 = templateList.filter(element => element.index === 1 || element.dimension === 2 );
// it will return 1st and 3rd objects
console.log(tl3) ;
【讨论】:
【参考方案6】:对于那些使用箭头函数寻找 ES6 替代方案的人,您可以执行以下操作。
let startsWith = wordToCompare => (element, index, array) =>
return element.indexOf(wordToCompare) === 0;
// where word would be your argument
let result = addressBook.filter(startsWith("word"));
使用includes的更新版本:
const startsWith = wordToCompare => (element, index, array) =>
return element.includes(wordToCompare);
【讨论】:
有什么方法可以从元素、索引和数组中传递不同的参数?例如,我想传递一个 X 变量。 @leandrotk 在这种情况下,“wordToCompare”是要传入的“X”变量。【参考方案7】:对于任何想知道为什么他们的胖箭头函数忽略 [, thisArg]
的人,例如为什么
["DOG", "CAT", "DOG"].filter(animal => animal === this, "DOG")
返回[]
这是因为 this
在这些箭头函数中是在创建函数时绑定的,并且在更广泛的包含范围内设置为 this
的值,因此 thisArg
参数被忽略。通过在父作用域中声明一个新变量,我很容易解决这个问题:
let bestPet = "DOG";
["DOG", "CAT", "DOG"].filter(animal => animal === bestPet);
=> ["DOG", "DOG"]
这里是更多阅读的链接: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions#No_separate_this
【讨论】:
【参考方案8】:有一种使用过滤器功能的简单方法,可以访问所有参数,而且不会过于复杂。
除非回调的 thisArg 设置为另一个范围过滤器不会创建自己的范围,我们可以访问当前范围内的参数。我们可以设置“this”来定义不同的范围,以便在需要时访问其他值,但默认情况下它设置为调用它的范围。您可以看到 this 用于 Angular 作用域in this stack。
使用 indexOf 违背了过滤器的目的,并增加了更多开销。过滤器已经在遍历数组了,为什么还要再遍历一遍呢?我们可以改为简单的pure function。
这是一个 React 类方法中的用例场景,其中状态有一个名为 items 的数组,通过使用过滤器我们可以检查现有状态:
checkList = (item) => // we can access this param and globals within filter
var result = this.state.filter(value => value === item); // returns array of matching items
result.length ? return `$item exists` : this.setState(
items: items.push(item) // bad practice, but to keep it light
);
【讨论】:
以上是关于如何在 Javascript .filter() 方法中将额外参数传递给回调函数?的主要内容,如果未能解决你的问题,请参考以下文章
如何创建 JSF 过滤器/url 模式来保护 javascript