我想将Array中的每个字符串与给定的字符串进行比较。我目前的实施是:
function startsWith(element) {
return element.indexOf(wordToCompare) === 0;
}
addressBook.filter(startsWith);
这个简单的函数有效,但只是因为现在 wordToCompare 被设置为全局变量,但当然我想避免这种情况并将其作为参数传递。我的问题是我不知道如何定义 startsWith()因此它接受一个额外的参数,因为我真的不明白它所采用的默认参数是如何传递的。我尝试了所有不同的方式,但没有一种方法可以工作。
如果您还可以解释传递的参数如何“内置”回调功能(对不起,我不知道这些更好的术语)工作会很棒
答案 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);
与函数表达式相比,箭头函数表达式具有更短的语法,并且词汇绑定此值(不绑定它自己的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)使用内联方式。
//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;
答案 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
});
}