简体   繁体   English

具有高阶函数的字符串方法

[英]String methods with higher-order functions

I ran into a weird thing while trying to use String methods with higher-order functions. 尝试使用具有高阶函数的String方法时,我遇到了一个奇怪的事情。 This will throw an error: 这会抛出一个错误:

['a', 'b'].some('boo'.includes)

I have to wrap the predicate in another function to make it work. 我必须将谓词包装在另一个函数中以使其工作。 But isn't 'boo'.includes already a function? 但不是'boo'.includes已经功能?

This works with plain functions: 这适用于普通函数:

const boo = {
    includes: () => true
};

['a', 'b'].some(boo.includes)

Is there some special property of String methods that prevents them from being composed like this? 是否有一些String方法的特殊属性阻止它们像这样组成?

"boo".includes is nothing else than String.prototype.includes . "boo".includes只不过是String.prototype.includes Calling it on the string "boo" however sets this to "boo", which gives the proper context to the function. 调用它的字符串“嘘”,然而将this以“嘘”,这给正确的上下文的功能。 Eg "boo".includes("b") is the same as String.prototype.includes.call("boo", "b") . 例如"boo".includes("b")String.prototype.includes.call("boo", "b")

Passing it as an argument, eg ['a', 'b'].some('boo'.includes) , is the same as ['a', 'b'].some(String.prototype.includes) , which then lacks the proper this as context. 将其作为参数传递,例如['a', 'b'].some('boo'.includes) ,与['a', 'b'].some(String.prototype.includes)相同['a', 'b'].some('boo'.includes) ['a', 'b'].some(String.prototype.includes) ,其中那么缺乏适当this作为背景。

You can of course use eg bind : ['a', 'b'].some(String.prototype.includes.bind("boo")) , or use the optional second parameter thisArg for some : ['a', 'b'].some(String.prototype.includes, "boo") . 当然,你可以使用例如bind['a', 'b'].some(String.prototype.includes.bind("boo"))或使用第二个可选参数thisArg对于some['a', 'b'].some(String.prototype.includes, "boo") This will get rid of the error. 这将摆脱错误。 However, you will then notice, that some passes not only the element, but the index as second parameter, and the array itself as third. 但是,您会注意到, some不仅传递了元素,还传递了索引作为第二个参数,而数组本身则传递给第三个参数。 This is a problem, as includes also takes an optional second parameter for the start position. 这是一个问题,因为includes了起始位置的可选第二个参数。 This causes likely unwanted behavior, as eg the array element "b" is at index 1, and "boo".includes("b", 1) === false . 这会导致可能不需要的行为,例如数组元素“b”在索引1处,而"boo".includes("b", 1) === false

All in all, you need a function which is so different to String.prototype.includes , that it's just easier to wrap it in a new function that actually does what you want: ['a', 'b'].some(e => "boo".includes(e)) , as you already noticed. 总而言之,你需要一个与String.prototype.includes完全不同的函数,它更容易将它包装在一个实际完成你想要的新函数中: ['a', 'b'].some(e => "boo".includes(e)) ,正如您已经注意到的那样。

Scott Marcus's comment is incorrect. Scott Marcus的评论不正确。 It's completely normal in functional programming to pass around functions without their required arguments. 函数式编程在没有所需参数的情况下传递函数是完全正常的。 Here's the actual problem: 这是实际问题:

The callback you pass to some is called with three arguments: currentValue , index , and array , and its this is set to undefined unless you pass a second parameter to some . 您传递给回调some被称为有三个参数: currentValueindex ,以及array ,它的this设置为undefined ,除非你通过第二个参数来some The method String.prototype.includes takes two arguments: search and start , and its this is used as the string to be searched. 该方法String.prototype.includes有两个参数: searchstart ,并且它的this作为要搜索的字符串。 As a result of this interaction, includes gets called without a string to search, so it gives an error. 作为此交互的结果, includes在没有字符串的情况下调用包进行搜索,因此它会出错。

Even if you fix the above via bind or by passing a second parameter to some , this won't entirely fix the problem though. 即使您通过bind或通过将第二个参数传递给some解决上述问题,但这并不能完全解决问题。 The other half of the problem is the second argument. 问题的另一半是第二个论点。 some considers it to be index but includes considers it to be start . some认为它是indexincludes认为它是start As a result, the b won't be searched for until the second character of the string, so even though the error will be gone, the test will still return false. 因此,在字符串的第二个字符之前不会搜索b ,因此即使错误消失,测试仍将返回false。

In this case, a wrapper function is unavoidable to get the desired behavior. 在这种情况下,包装函数不可避免地获得所需的行为。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM