为什么 JavaScript 的扩展语法允许 {...null} 但不允许 [...null]?

Why does JavaScript's spread syntax allow {...null} but not [...null]?

今天正在更新一些代码,return将可选道具添加到 React 组件。我发现即使函数有时 returns null,当立即解包 return 值时它也不会出错。

迂腐的代码总结:

const returnPropsOrDont = (condition) => {
  if (condition) return null;
  return { optionalProp: 'foo' };
}
...
render() {
  const { condition } = props;
  return <SomeComponent
           staticProp="staticProp"
           {...returnPropsOrDont(condition)}
         />
}

意识到这很酷后,我 运行 控制台并在对象和数组上试用了它。唉-

   > {...null} // {}
   > {...undefined} // {}, which is interesting because null is an object but undefined is not
   > [...null] // Uncaught TypeError: object null is not iterable

我做了一些简单的谷歌搜索和 found one article 这表明 TypeScript 认为这是一项功能,可以确保可选定义的值不会困扰毫无戒心的开发人员。很好,但是 a) 我没有使用 TypeScript,并且 b) 我不知道为什么 JS 不以同样的方式保护数组。

既然这看起来像是对可选定义值的防范,为什么 {...null} 可以而 [...null] 不行?

[…null] - 这里使用了 spear 运算符,它仅适用于可迭代对象(如字符串、数组、生成器或自定义可迭代对象),但 null 不是可迭代对象并且会收到错误。您可以通过添加特殊的 属性 符号来创建自己的可迭代对象。迭代器

{...null} - 有效是因为 typeof null == 'object',但在现实生活中它没有意义

通常,...x 的使用要求 x 可迭代的 因为 ... 的要点通常是将一个可迭代对象展开为它的组件。数组是可迭代对象的主要示例。

null 不是 可迭代的 。它没有组件,因此迭代 null 没有意义。 for (const e of null) 同样会失败,因为 of 也需要一个 iterable.

但是,{...x} 要求 x 可枚举的 ,因为它不仅需要值,还需要键。对象是可枚举的主要示例。

null 可枚举的 null 有时被视为对象,这就是其中一种情况。对象是可枚举的,因为它们可以具有属性。 for (const p in null) 同样会成功,因为 in 需要一个 enumerable.