DEV Community

NikiMunger
NikiMunger

Posted on

在js数组中 undefined和空槽(empty slot)的区别

  • undefined 是一个真实存在的值,数组里真的存了一个元素,只是值是 undefined。
  • 空槽(empty slot)根本没有元素,索引不存在,就像那个格子不存在。

区别

1.创建方式不同

const a = [1, undefined, 3];
const b = [1, , 3];   // 注意这里的逗号 ,, 产生了空槽
Enter fullscreen mode Exit fullscreen mode
  • a[1] 的值是 undefined(数组里真的有一个元素)
  • b[1] 是一个“空槽”,数组索引 1 处根本没有元素

2."in" 运算符区别

1 in a   // true,因为有元素,只是值是 undefined
1 in b   // false,因为它是空槽,不存在元素
Enter fullscreen mode Exit fullscreen mode

3.数组长度长度一样,但内容不同

a.length // 3
b.length // 3
Enter fullscreen mode Exit fullscreen mode

长度一样,但内部结构不一样。

4.forEach / map / filter 之类对空槽会跳过

a.forEach((v,i)=>console.log(i, v));
// 输出:0 1, 1 undefined, 2 3

b.forEach((v,i)=>console.log(i, v));
// 输出:0 1, 2 3    (索引1被跳过)
Enter fullscreen mode Exit fullscreen mode

5.JSON.stringify 的区别

JSON.stringify([1, undefined, 3])
// "[1,null,3]"   undefined 转成 null

JSON.stringify([1, , 3])
// "[1,null,3]"   空槽也转成 null
Enter fullscreen mode Exit fullscreen mode

注意:虽然结果一样,但内部意义不同。

6.map 的行为更明显

[1, undefined, 3].map(x => 100)
// [100, 100, 100]
[1, , 3].map(x => 100)
// [100, , 100]   // 注意空槽保留为空槽!
Enter fullscreen mode Exit fullscreen mode

空槽不会被 map 处理,也不会变为 undefined,而是继续保持空槽。

7.数组序列化展开时的区别

[...a] // [1, undefined, 3]

[...b] // [1, undefined, 3]   <-- 空槽在展开时会变成 undefined
Enter fullscreen mode Exit fullscreen mode

创建空槽的行为

  1. Array 构造函数(单个数字参数)

    const a = Array(3);  // [empty x 3]
    
  2. 数组字面量中使用省略的逗号

    const a = [1, , 3];  // 中间是空槽
    
  3. 使用 delete 删除数组元素

    const a = [1,2,3];
    delete a[1];         // [1, empty, 3]
    
  4. 使用稀疏数组赋值跳过索引

    const a = [];
    a[2] = 'x';          // [empty x 2, "x"]
    
  5. 使用 map/filter/slice 等操作保留空槽

    [ , 1, , 2].map(x => x)  // 仍然是 [empty, 1, empty, 2]
    
  6. 使用 holes 的数组做扩展、解构(会变 undefined,但原数组仍然有空槽)

    const a = [ , 2, 3];
    const b = [...a];   // b 里不是空槽,是 undefined
                        // a 自身仍然有空槽
    

创建 undefined 元素的行为

  1. 普通赋值

    const a = [];
    a[0] = undefined;   // 明确设置
    
  2. 使用扩展运算符展开空槽数组

    const a = [ , 1];
    const b = [...a];   // b = [undefined, 1]
    
  3. 使用解构赋值展开空槽

    const [a, b] = [, 1]; // a === undefined
    
  4. JSON.parse 解析含 null 的 json(与 undefined 不同,但不会产生空槽)

    JSON.parse("[1, null, 3]")  // [1, null, 3]
    

    (这里不会产生空槽,而是“null”,我放在这里是为了对比。)

  5. map/filter 等回调返回 undefined

    [1,2,3].map(x => undefined); // [undefined, undefined, undefined]
    
  6. 函数返回 undefined 导致数组填充 undefined

    const a = Array.from([1,,3], x => x);  
    // => [1, undefined, 3]
    
  7. 直接写 undefined 作为数组元素

    [undefined, 2, undefined]
    

Top comments (0)