javascript Array.includes的函数用法导致TypeError [重复]

hkmswyz6  于 2023-02-02  发布在  Java
关注(0)|答案(2)|浏览(129)
    • 此问题在此处已有答案**:

(13个答案)
2天前关闭。
我本以为[1].some([1].includes)会返回true,但却得到一个错误消息:
未捕获的类型错误:无法将undefined或null转换为对象。
有什么想法会导致这种情况吗?据我所知,Array.some接受一个函数调用每个数组项,[1].includes应该履行。

rta7y2nd

rta7y2nd1#

当您按原样传递该函数时,将丢失上下文:当它作为回调调用时,它内部的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));

......让这件事变得更灵活。

nfg76nw0

nfg76nw02#

这取决于您所使用的JS引擎中includes的具体实现,但通常标准库函数对于无点风格编程来说并不是很协作。
通常,这是因为上下文(this)未按预期分配。尝试执行以下操作可以显示此问题:

[1].some([1].includes); // Error
[1].some([1].includes.bind([1])) // true

编辑:这个答案并不完全正确,你应该看看rain77ow的答案above

相关问题