如何在Javascript .filter()方法中将额外的参数传递给回调函数?


104

我想将数组中的每个字符串与给定的字符串进行比较。我当前的实现是:

function startsWith(element) {
    return element.indexOf(wordToCompare) === 0;
}
addressBook.filter(startsWith);

这个简单的函数有效,但是仅因为现在将wordToCompare设置为全局变量,但是我当然想避免这样做并将其作为参数传递。我的问题是我不确定如何定义startsWith(),因此它不能接受一个额外的参数,因为我不太了解如何传递其默认参数。我已经尝试过所有可以想到的不同方式,但没有一种有效。

如果您还可以解释将参数传递给“内置”回调函数的方法(对不起,我不知道这些参数有更好的用语)会很好

Answers:


152

使startsWith接受单词进行比较并返回一个函数该函数将随后用作过滤器/回调函数:

function startsWith(wordToCompare) {
    return function(element) {
        return element.indexOf(wordToCompare) === 0;
    }
}

addressBook.filter(startsWith(wordToCompare));

另一个选择是使用Function.prototype.bind [MDN](仅在支持ECMAScript 5的浏览器中可用,请为较旧的浏览器使用填充程序链接)并“修复”第一个参数:

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;
}

1
好的,现在我明白了。我试图将参数直接传递给回调函数...我确实需要使用我的JavaScript。
谢谢费利克斯

传递其他参数呢?我尝试传递一组参数,但这似乎失败了
geotheory 2014年

@geotheory:他们呢?您可以像其他任何函数一样传递多个参数。
Felix Kling 2014年

函数名称后的bind(this)以及filter()链接帮助我在函数内部使用.this。谢谢。
萨加尔·哈特里

108

过滤器的第二个参数将设置这个回调的内部。

arr.filter(callback[, thisArg])

因此,您可以执行以下操作:

function startsWith(element) {
    return element.indexOf(this) === 0;
}
addressBook.filter(startsWith, wordToCompare);

7
我发现这是最好的答案。
杰夫·吉尔伯特

所以现在将新数组分配给wordToCompare对象,对吗?以后如何使用wordToCompare对象访问新数组?
Badhon Jain

最佳答案。非常适合过滤器和查找。两者均基于WC3文档:​​thisValue-可选。要传递给函数的值用作其“ this”值。如果这个参数是空的,值“未定义”将作为其“本”价值传递
richaa

1
@TarekEldeeb刚刚传递了您制作的对象{one: 'haha', two:'hoho'}
toddmo

2
这是一个很好的例子,说明了答案之间在复杂性,复杂程度和复杂程度方面可能存在巨大差异
toddmo

13

对于使用箭头功能寻找ES6替代产品的用户,可以执行以下操作。

let startsWith = wordToCompare => (element, index, array) => {
  return element.indexOf(wordToCompare) === 0;
}

// where word would be your argument
let result = addressBook.filter(startsWith("word"));

使用包括的更新版本:

const startsWith = wordToCompare => (element, index, array) => {
  return element.includes(wordToCompare);
}

有什么方法可以传递与element,index和array不同的参数?例如,我想传递一个X变量。
leandrotk

@leandrotk在这种情况下“wordToCompare”是“X”变量中进行传递。
GetBackerZ

11
function startsWith(element, wordToCompare) {
    return element.indexOf(wordToCompare) === 0;
}

// ...
var word = "SOMETHING";

addressBook.filter(function(element){
    return startsWith(element, word);
});

4

您可以在过滤器中使用箭头功能,如下所示:

result = addressBook.filter(element => element.indexOf(wordToCompare) === 0);

MDN上的箭头功能

箭头函数表达式的语法比函数表达式短,并且按词法绑定此值(不绑定其自身的this,arguments,super或new.target)。箭头函数始终是匿名的。这些函数表达式最适合非方法函数,因此不能用作构造函数。


注意:IE上不支持
Luis Lavieri

1

对于任何想知道为什么他们的胖箭头功能被忽略的人[, 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/zh-CN/docs/Web/JavaScript/Reference/Functions/Arrow_functions#No_separate_this


0

基于奇怪的答案和 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter

我以两种不同的方式做到了。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) ;


0

有一种简单的方法可以使用过滤器功能,访问所有参数,而不会使其复杂化。

除非将回调的thisArg设置为另一个作用域,否则过滤器不会创建自己的作用域,并且我们可以访问当前作用域内的参数。我们可以设置'this'定义不同的作用域,以便在需要时访问其他值,但是默认情况下,它设置为从其调用的作用域。您可以在此堆栈中看到其用于Angular范围。

使用indexOf违反了过滤器的目的,并增加了更多开销。过滤器已经在数组中遍历了,为什么我们需要再次遍历它呢?相反,我们可以使其成为一个简单的纯函数

这是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
  });
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.