如何在 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 =&gt; 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() 方法中将额外参数传递给回调函数?的主要内容,如果未能解决你的问题,请参考以下文章

如何实现JavaScript的Map和Filter函数?

如何创建 JSF 过滤器/url 模式来保护 javascript

在 JavaScript 中,如何求出两个数组的交集和差集?

JavaScript 如何解析链式三元表达式?

JavaScript 数组方法filter和reduce

javascript中filter的用法