为什么map,every和其他数组函数会跳过空值?

Joe*_*oyd 14 javascript

背景

我正在编写一些代码来检查2个数组是否相同,但是由于某种原因,当期望为false时结果为true。仔细检查后发现,未定义的数组值被跳过。

const arr1 = [, , 3, 4]
const arr2 = [1, 2, 3, 4]
const result = arr1.every((item, index) => item === arr2[index])
console.log(result) // true (HOW????)
Run Code Online (Sandbox Code Playgroud)

我尝试过的

因此,我花了一些时间尝试正确获取此处的值,但我想到的唯一一件事是常规的for循环,该循环基于数组长度而不是实际项目进行迭代。

为什么会发生这种情况,有没有办法识别我数组中的这些空/未定义的值?

T.J*_*der 12

forEach仅访问实际存在的元素这一事实的延伸。我不知道还有更深层的“为什么”,除了为缺少的元素调用回调没有多大意义。

您可以使用以下方法实现这些元素(如果就是世界):

  1. 传播符号,或
  2. Array.from, 要么
  3. Array.prototype.values, 要么
  4. Array.prototype.entries

...或者可能是其他一些。

const a = [, , 3];
console.log(a.hasOwnProperty(0)); // false
const b = [...a];
console.log(b.hasOwnProperty(0)); // true
const c = Array.from(a);
console.log(b.hasOwnProperty(0)); // true
Run Code Online (Sandbox Code Playgroud)

将其应用于您的功能Array.from

const arr1 = [, , 3, 4]
const arr2 = [1, 2, 3, 4]
const result = Array.from(arr1).every((item, index) => item === arr2[index])
console.log(result) // false
Run Code Online (Sandbox Code Playgroud)

当然,这涉及到创建一个新数组并循环遍历前一个元素。使用自己的for循环可能会更好。

适用Array.prototype.entries于您的功能:

const arr1 = [, , 3, 4]
const arr2 = [1, 2, 3, 4]
let result = true;
for (const [index, value] of arr1.entries()) {
    if (value !== arr2[index]) {
        result = false;
        break;
    }
}
console.log(result) // false
Run Code Online (Sandbox Code Playgroud)


Que*_*tin 5

因为语言设计就是这么说的。\xe2\x80\x8d\xe2\x99\x82\xef\xb8\x8f

\n\n

请参阅规格说明

\n\n
\n
    \n
  • 重复,当 k < len\n \n
      \n
    • 令 Pk 为 ToString(k)。
    • \n
    • kPresent 为 HasProperty (O, Pk)。
    • \n
    • ReturnIfAbrupt(kPresent)。
    • \n
    • 如果 kPresent 为 true,则
    • \n
  • \n
\n
\n\n

\xe2\x80\xa6 然后进行操作。

\n\n

由于从未将值分配给01属性,因此HasProperty测试会给出结果false,因此规则会跳过它们If

\n