Array.includes 的功能使用导致 TypeError [重复]
我期望
[1].some([1].includes)
返回 true,但我收到一条错误消息:
Uncaught TypeError: Cannot convert undefined or null to object.
您知道是什么原因导致的吗?据我了解,
Array.some
接受每个数组项调用的函数,
[1].includes
应该会执行该函数。
如果按原样传递该函数,则会丢失上下文:当将其作为回调调用时,严格模式下,其内部的
this
值为
undefined
(非严格模式下为全局对象),而不是
[1]
。要解决此问题,您可以修复上下文:
[1].some([].includes.bind([1]))
请注意,使用哪个数组访问
includes
函数并不重要;您不妨将其写为...
[1].some( Array.prototype.includes.bind([1]) )
这有点不太简洁,但效率更高(因为没有创建直接数组)。不过,它几乎永远不会成为瓶颈;因此您应该更好地优化可读性。
不幸的是,这还不够。请参阅, Array.includes() 使用 两个 参数:
arr.includes(searchElement[, fromIndex])
... 并且
Array.some()
确实
为其提供了这两个参数(实际上甚至有三个,但
includes
只使用了两个)。这就是为什么这个...
[1,2,3].some([].includes.bind([1])); // true
... 有效,但是这个...
[2,1,3].some([].includes.bind([1])); // false
... 无效:
[1]
数组中的查找从第 0、第 1、第 2 个元素开始 - 并且显然在第一个元素之后失败。
要解决此问题,您可以创建一个只接受一个参数的函数,例如 lodash 的 _.unary :
[2,1,3].some(_.unary([].includes.bind([1]))) // now we're talking!
... 或者咬紧牙关,改用箭头函数。请注意,您仍然可以在此处使用具有绑定上下文的函数:
const checker = [].includes.bind([1]);
[2,1,3].some(el => checker(el));
... 以使其更加灵活。
这取决于您使用的 JS 引擎中
includes
的具体实现,但通常标准库函数对于无点式编程不太适用。
通常这是因为上下文 (
this
) 未按预期分配。这可以通过尝试以下内容来显示:
[1].some([1].includes); // Error
[1].some([1].includes.bind([1])) // true
编辑:这个答案并不完全正确。您可能应该阅读 rain77ow 的答案 上面