如何在 Javascript .filter() 方法中将额外的参数传递给回调函数?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7759237/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I pass an extra parameter to the callback function in Javascript .filter() method?
提问by agente_secreto
I want to compare each string in an Array with a given string. My current implementation is:
我想将数组中的每个字符串与给定的字符串进行比较。我目前的实现是:
function startsWith(element) {
return element.indexOf(wordToCompare) === 0;
}
addressBook.filter(startsWith);
This simple function works, but only because right now wordToCompareis being set as a global variable, but of course I want to avoid this and pass it as a parameter. My problem is that I am not sure how to define startsWith()so it accepts one extra parameter, because I dont really understand how the default parameters it takes are passed. I've tried all the different ways I can think of and none of them work.
这个简单的函数有效,但只是因为现在wordToCompare被设置为全局变量,但当然我想避免这种情况并将其作为参数传递。我的问题是我不确定如何定义startsWith()所以它接受一个额外的参数,因为我真的不明白它所采用的默认参数是如何传递的。我已经尝试了所有我能想到的不同方法,但都没有奏效。
If you could also explain how the passed parameters to 'built in' callback functions (sorry, I dont know of a better term for these) work that would be great
如果您还可以解释传递给“内置”回调函数的参数(抱歉,我不知道这些更好的术语)如何工作,那就太好了
回答by Felix Kling
Make startsWith
accept the word to compare against and return a functionwhich will then be used as filter/callback function:
请startsWith
接受这个词来比较和返回功能,这将被用来作为过滤器/回调函数:
function startsWith(wordToCompare) {
return function(element) {
return element.indexOf(wordToCompare) === 0;
}
}
addressBook.filter(startsWith(wordToCompare));
Another option would be to use Function.prototype.bind
[MDN](only available in browser supporting ECMAScript 5, follow a link for a shim for older browsers) and "fix" the first argument:
另一种选择是使用Function.prototype.bind
[MDN](仅在支持 ECMAScript 5 的浏览器中可用,请点击旧浏览器的垫片链接)并“修复”第一个参数:
function startsWith(wordToCompare, element) {
return element.indexOf(wordToCompare) === 0;
}
addressBook.filter(startsWith.bind(this, wordToCompare));
I dont really understand how the default parameters it takes are passed
我真的不明白它所采用的默认参数是如何传递的
There is nothing special about it. At some point, filter
just calls the callback and passes the current element of the array. So it's a function calling another function, in this case the callback you pass as argument.
没有什么特别之处。在某些时候,filter
只需调用回调并传递数组的当前元素。所以它是一个调用另一个函数的函数,在这种情况下是你作为参数传递的回调。
Here is an example of a similar function:
下面是一个类似函数的例子:
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;
}
回答by Jeff
The second parameter of filter will set thisinside of the callback.
filter 的第二个参数将在回调中设置它。
arr.filter(callback[, thisArg])
So you could do something like:
所以你可以这样做:
function startsWith(element) {
return element.indexOf(this) === 0;
}
addressBook.filter(startsWith, wordToCompare);
回答by jhamPac
For those looking for an ES6 alternative using arrow functions, you can do the following.
对于那些使用箭头函数寻找 ES6 替代方案的人,您可以执行以下操作。
let startsWith = wordToCompare => (element, index, array) => {
return element.indexOf(wordToCompare) === 0;
}
// where word would be your argument
let result = addressBook.filter(startsWith("word"));
Updated version using includes:
更新版本使用包括:
const startsWith = wordToCompare => (element, index, array) => {
return element.includes(wordToCompare);
}
回答by James Montagne
function startsWith(element, wordToCompare) {
return element.indexOf(wordToCompare) === 0;
}
// ...
var word = "SOMETHING";
addressBook.filter(function(element){
return startsWith(element, word);
});
回答by oddRaven
You can use the arrow function inside a filter, like this:
您可以在过滤器中使用箭头函数,如下所示:
result = addressBook.filter(element => element.indexOf(wordToCompare) === 0);
An arrow function expression has a shorter syntax compared to function expressions and lexically binds the this value (does not bind its own this, arguments, super, or new.target). Arrow functions are always anonymous. These function expressions are best suited for non-method functions and they can not be used as constructors.
与函数表达式相比,箭头函数表达式的语法更短,并且在词法上绑定 this 值(不绑定自己的 this、arguments、super 或 new.target)。箭头函数总是匿名的。这些函数表达式最适合非方法函数,它们不能用作构造函数。
回答by JKettler
For anyone wondering why their fat arrow function is ignoring [, thisArg]
, e.g. why
对于任何想知道为什么他们的胖箭头函数被忽略的人[, thisArg]
,例如为什么
["DOG", "CAT", "DOG"].filter(animal => animal === this, "DOG")
returns []
["DOG", "CAT", "DOG"].filter(animal => animal === this, "DOG")
返回 []
it's because this
inside those arrow functions are bound when the function is created and are set to the value of this
in the broader encompassing scope, so the thisArg
argument is ignored. I got around this pretty easily by declaring a new variable in a parent scope:
这是因为this
这些箭头函数在创建函数时被绑定,并被设置为this
更广泛的包含范围内的值,因此thisArg
参数被忽略。通过在父作用域中声明一个新变量,我很容易地解决了这个问题:
let bestPet = "DOG";
["DOG", "CAT", "DOG"].filter(animal => animal === bestPet);
=> ["DOG", "DOG"]
let bestPet = "DOG";
["DOG", "CAT", "DOG"].filter(animal => animal === bestPet);
=> ["DOG", "DOG"]
Here is a link to some more reading: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions#No_separate_this
这是更多阅读的链接:https: //developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions#No_separate_this
回答by DBrown
There is an easy way to use the filter function, access all params, and not over complicate it.
有一种简单的方法可以使用过滤器功能,访问所有参数,并且不会使其过于复杂。
Unless the callback's thisArgis set to another scope filter does not create its own scope, and we can access params within the current scope. We can set 'this' to define a different scope in order to access other values if needed, but by default it is set to the scope it's called from. You can see thisbeing used for Angular scopes in this stack.
除非回调的thisArg设置为另一个范围过滤器不会创建自己的范围,我们可以访问当前范围内的参数。我们可以设置 'this' 来定义不同的作用域,以便在需要时访问其他值,但默认情况下,它被设置为调用它的作用域。你可以看到这个被用于角范围在这个堆栈。
Using indexOf is defeating the purpose of filter, and adding more overhead. Filter is already going through the array, so why do we need to iterate through it again? We can instead make it a simple pure function.
使用 indexOf 违背了过滤器的目的,并增加了更多的开销。Filter 已经在遍历数组了,那么为什么我们需要再次遍历它呢?我们可以改为使它成为一个简单的纯函数。
Here's a use-case scenario within a React class method where the state has an array called items, and by using filter we can check the existing state:
这是 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 Ashish
based on oddRaven answer and https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
基于oddRaven 答案和 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
i did it 2 different way . 1) using function way . 2) using inline way .
我做了两种不同的方式。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) ;