【问题标题】:Spreading undefined in array vs object在数组与对象中传播未定义
【发布时间】:2018-04-19 16:33:47
【问题描述】:

为什么在对象中传播 undefined 会返回一个空对象? {...undefined} // equals {}:

console.log({...undefined})

为什么在数组中传播 undefined 会给你一个错误? [...undefined] // type error:

console.log([...undefined])

【问题讨论】:

标签: javascript ecmascript-6 spread-syntax


【解决方案1】:

你可以使用这个表达式 [...(this.options || [])],其中 options 是数组

【讨论】:

    【解决方案2】:

    通常,...x 的使用要求 x可迭代的,因为 ... 的目的通常是将可迭代对象展平为其组件。

    但是,{...x} 要求 x可枚举的,因为我们不仅需要值,还需要键。

    null 不是可迭代。它没有组件,因此迭代null 没有意义。 (for (const item of null) 同样会失败。)

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

    【讨论】:

      【解决方案3】:

      如 cmets 中所述,并由 @ftor 从 #687 总结,对象传播等同于1Object.assign()(问题 #687#45),而在数组中传播文字上下文是可迭代传播的。

      引用Ecma-262 6.0,Object.assign()定义为:

      19.1.2.1 Object.assign(目标,...来源)

      assign 函数用于将所有可枚举自身属性的值从一个或多个源对象复制到目标对象。当调用assign函数时,会采取以下步骤:

      1. 成为ToObject(目标)。
      2. ReturnIfAbrupt(to)。
      3. 如果只传递了一个参数,则返回。
      4. 让源是从第二个参数开始的参数值的List
      5. 对于每个元素 nextSource 的来源,按索引升序,执行
        1. 如果 nextSource 为 undefinednull,则让键为空 List
        2. 否则,...

      ...接着是复制自己的属性的描述。 Object Rest/Spread Properties 的草案是here。它不是 Ecma-262 6.0 的一部分。

      数组文字表达式中的SpreadElement定义如下:

      SpreadElement : ... AssignmentExpression

      1. spreadRef 成为评估 AssignmentExpression 的结果。
      2. spreadObjGetValue(spreadRef)。
      3. iteratorGetIterator(spreadObj)。
      4. ReturnIfAbrupt(迭代器)。

      并且由于undefined 没有带有键@@iterator 的属性,因此根据GetIterator 的步骤抛出TypeError。该标准不容易阅读,但如果我没记错的话,错误的路径是GetIterator -> GetMethod -> GetV -> ToObject,它会为 undefined 和 null 引发 TypeError。

      在数组初始化中使用可能未定义值的变量的简单补救措施是使用默认值:

      const maybeArray = undefined;
      const newArray = [ ...(maybeArray || []) ];
      

      1how setters are handled有区别。

      【讨论】:

        猜你喜欢
        • 2017-07-04
        • 2021-12-21
        • 2021-12-01
        • 1970-01-01
        • 2017-04-12
        • 2019-06-14
        • 1970-01-01
        • 2015-12-31
        相关资源
        最近更新 更多