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

时间:2011-10-13 19:12:03

标签: javascript callback scope

我想将Array中的每个字符串与给定的字符串进行比较。我目前的实施是:

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

这个简单的函数有效,但只是因为现在 wordToCompare 被设置为全局变量,但当然我想避免这种情况并将其作为参数传递。我的问题是我不知道如何定义 startsWith()因此它接受一个额外的参数,因为我真的不明白它所采用的默认参数是如何传递的。我尝试了所有不同的方式,但没有一种方法可以工作。

如果您还可以解释传递的参数如何“内置”回调功能(对不起,我不知道这些更好的术语)工作会很棒

8 个答案:

答案 0 :(得分:137)

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 :(得分:90)

过滤器的第二个参数会在回调中设置 this

arr.filter(callback[, thisArg])

所以你可以这样做:

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

答案 2 :(得分:11)

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

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

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

答案 3 :(得分:7)

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

int

使用includes更新版本:

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

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

答案 4 :(得分:3)

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

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

Arrow functions on MDN

  

与函数表达式相比,箭头函数表达式具有更短的语法,并且词汇绑定此值(不绑定它自己的this,arguments,super或new.target)。箭头功能始终是匿名的。这些函数表达式最适合非方法函数,不能用作构造函数。

答案 5 :(得分: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"]

以下是更多阅读的链接: Append

答案 6 :(得分:0)

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

我做了两种不同的方式。 1)使用功能方式。 2)使用内联方式。

&#13;
&#13;
//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) ;
&#13;
&#13;
&#13;

答案 7 :(得分:0)

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

除非将回调的 thisArg 设置为另一个范围过滤器,否则不会创建自己的范围,我们可以访问当前范围内的参数。我们可以设置这个&#39;定义一个不同的范围,以便在需要时访问其他值,但默认情况下,它被设置为调用它的范围。您可以看到用于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
  });
}