gpt4 book ai didi

javascript - Array.prototype.includes 中的错误?

转载 作者:搜寻专家 更新时间:2023-10-31 23:28:42 24 4
gpt4 key购买 nike

我在一种边缘情况下遇到了 Array.prototype.includes 的奇怪行为。

鉴于 Array.prototype.includes 在绑定(bind)上下文中工作,人们可能会像这样使用它(这是有效的)

expect(Array.prototype.includes.call([1, 2], 1))).toBe(true)

简单地说,我们绑定(bind)数组 [1, 2] 并测试 1 是否包含在内。

然后考虑,许多 Array.prototype 方法能够将上下文绑定(bind)到提供的回调,因此例如 Array.prototype.some 可以与 Object.prototype.hasOwnProperty像这样

expect(["foo", "bar"].some(Object.prototype.hasOwnProperty, { foo: 0 })).toBe(true)

这里,.some接受两个参数,(callback, [thisArg]),其中可选的thisArg,当提供时,绑定(bind)到回调,因此前面的示例将 { foo: 0 } 绑定(bind)到回调 Object.prototype.hasOwnProperty,然后测试 ["foo", "bar"] 中的所有项目 如果至少有一个是 { foo: 0 } 的自有属性。此示例也有效。

但是如果您尝试使用 Array.prototype.includes 作为回调,就会发生一些奇怪的事情。

[0, 1].some(Array.prototype.includes, [1]) // => false

这里我们将数组 [1] 绑定(bind)到 Array.prototype.includes 并且我们测试 [0, 1] 的每一项如果在至少包括一个。但是这种情况返回 false,这出乎我们的意料。

奇怪的是,如果绑定(bind)数组包含 1 以外的数字或包含多个项目,则测试通过

[0, 1].some(Array.prototype.includes, [0]) // => true
[0, 1].some(Array.prototype.includes, [1, 1]) // => true
// but
[0, 1].some(Array.prototype.includes, [1]) // => false

似乎数组 [1] 处理不当。

测试于 Node v.11.11.0 Node v.8.11.3和 Chrome 73

我基本上只测试了 V8 引擎。任何人都可以用 Chakra 报告输出吗?

最佳答案

这不是 includes 中的错误. :-)

问题是 includes接受可选的第二个参数,即开始搜索的索引,以及 some为其回调提供三个参数:项目、其索引和正在搜索的对象。

所以

[0, 1].some(Array.prototype.includes, [1])

这些调用(有效):

  • [1].includes(0, 0) - 错误,数组不包含 0
  • [1].includes(1, 1) - 错误,数组包含 1在索引 0 , 但搜索从索引 1 开始

这会定期出现。例如,尝试使用 parseInt 时由于 parseInt,作为直接将字符串数组转换为数字数组的回调的第二个参数(要使用的基数或基数):

console.log(["6", "9", "7"].map(parseInt));

97失败是因为调用(有效):

  • parseInt("6", 0) - 因为 parseInt 有效忽略无效基数 0 .
  • parseInt("9", 1) - NaN因为parseInt总是返回 NaN对于基数 1
  • parseInt("7", 2) - NaN因为"7"不是以 2 为基数(二进制)的有效数字

故事的寓意:记住那些不常用的论点 map , some , forEach ,以及提供给回调的各种其他方法。 :-)


在我工作的一个代码库中,他们有一个 clamp函数接受一个函数并确保,无论调用它有多少参数,它只会传递所需数量的参数。如果您使用的是 includes像这样很多,你可以创建一个夹紧的 includes :

function clamped(fn, count) {
return function(...args) {
return fn.apply(this, args.slice(0, count));
}
}

const includes = clamped(Array.prototype.includes, 1);

console.log([0, 1].some(includes, [1])); // true
console.log([0, 1].some(includes, [3])); // false

方便的是 includes可重复使用。

当然,也可以使用包装函数:

console.log([0, 1].some(function(entry) {
return this.includes(entry);
}, [1])); // true
console.log([0, 1].some(function(entry) {
return this.includes(entry);
}, [3])); // false


当然,这些都是通用解决方案。如果你特别想知道数组 a包含数组 b 中的任何条目,根据 a 的特征,您可以构建更具体的实现来有效地处理该问题和 b .

关于javascript - Array.prototype.includes 中的错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55991639/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com