[英]String methods with higher-order functions
尝试使用具有高阶函数的String方法时,我遇到了一个奇怪的事情。 这会抛出一个错误:
['a', 'b'].some('boo'.includes)
我必须将谓词包装在另一个函数中以使其工作。 但不是'boo'.includes
已经功能?
这适用于普通函数:
const boo = {
includes: () => true
};
['a', 'b'].some(boo.includes)
是否有一些String方法的特殊属性阻止它们像这样组成?
"boo".includes
只不过是String.prototype.includes
。 调用它的字符串“嘘”,然而将this
以“嘘”,这给正确的上下文的功能。 例如"boo".includes("b")
与String.prototype.includes.call("boo", "b")
。
将其作为参数传递,例如['a', 'b'].some('boo'.includes)
,与['a', 'b'].some(String.prototype.includes)
相同['a', 'b'].some('boo'.includes)
['a', 'b'].some(String.prototype.includes)
,其中那么缺乏适当this
作为背景。
当然,你可以使用例如bind
: ['a', 'b'].some(String.prototype.includes.bind("boo"))
或使用第二个可选参数thisArg对于some
: ['a', 'b'].some(String.prototype.includes, "boo")
。 这将摆脱错误。 但是,您会注意到, some
不仅传递了元素,还传递了索引作为第二个参数,而数组本身则传递给第三个参数。 这是一个问题,因为includes
了起始位置的可选第二个参数。 这会导致可能不需要的行为,例如数组元素“b”在索引1处,而"boo".includes("b", 1) === false
。
总而言之,你需要一个与String.prototype.includes
完全不同的函数,它更容易将它包装在一个实际完成你想要的新函数中: ['a', 'b'].some(e => "boo".includes(e))
,正如您已经注意到的那样。
Scott Marcus的评论不正确。 函数式编程在没有所需参数的情况下传递函数是完全正常的。 这是实际问题:
您传递给回调some
被称为有三个参数: currentValue
, index
,以及array
,它的this
设置为undefined
,除非你通过第二个参数来some
。 该方法String.prototype.includes
有两个参数: search
和start
,并且它的this
作为要搜索的字符串。 作为此交互的结果, includes
在没有字符串的情况下调用包进行搜索,因此它会出错。
即使您通过bind
或通过将第二个参数传递给some
解决上述问题,但这并不能完全解决问题。 问题的另一半是第二个论点。 some
认为它是index
但includes
认为它是start
。 因此,在字符串的第二个字符之前不会搜索b
,因此即使错误消失,测试仍将返回false。
在这种情况下,包装函数不可避免地获得所需的行为。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.