如果不能迭代,对象散布如何工作?

Cer*_*ean 6 javascript javascript-objects ecmascript-6

我正在学习传播的新用途。我意识到对象传播是ES2018的建议。它以下列方式在节点10.5中工作:

const oldObj = {name:"doug", age:34};
const newObj = {...oldObj}; 
console.log(newObj); // { name: 'doug', age: 34 }
Run Code Online (Sandbox Code Playgroud)

扩展的一种有趣用途是将可迭代对象转换为数组。例如,它可以与Maps配合使用,为您提供一组值对数组

const mappie = new Map().set("name", "doug").set("age", 234).set("profession", "seeker of Cthulhu");

const arr1 = [...mappie];

console.log(arr1); // [ [ 'name', 'doug' ], [ 'age', 234 ], [ 'profession', 'seeker of Cthulhu' ] ]
Run Code Online (Sandbox Code Playgroud)

但是我不能在对象上使用它

const obj = {
  name: "doug",
  age: 234,
  profession: "seeker of Chthulhu"
};

const arr2 = [...obj];
console.log(arr2);
Run Code Online (Sandbox Code Playgroud)

给我

TypeError: obj is not iterable
Run Code Online (Sandbox Code Playgroud)

好的,我知道该对象目前是不可迭代的。但是,物体在传播某种与可重复传播的生物不同吗?那是它在某些情况下会起作用,而在另一些情况下则不会,并且应该只意识到对象只能传播到对象中,而不能将它们传播到数组中?还是我错过了全局?我正在尝试了解传播的新用途,并希望得到任何启发。

T.J*_*der 9

但是对象传播是某种与可迭代传播不同的生物吗?

是的。属性传播根本不使用迭代。这是新的主要语法,其运行时语义由 spec定义,而不是根据可迭代/迭代:

属性定义:...赋值表达式

  1. 令 exprValue 是对 AssignmentExpression 求值的结果。
  2. 让 fromValue 是?获取值(exprValue)。
  3. 让excludedNames 成为一个新的空列表。
  4. 返回 ?CopyDataProperties(对象,fromValue,excludedNames)。

属性传播专门针对对象属性,没有像可迭代传播那样对其进行额外的概括。(也不是很明显会有。:-))

对于您的const arr2 = [...obj];用例,您可能需要Object.entries

const arr2 = Object.entries(obj);
Run Code Online (Sandbox Code Playgroud)

例子:

const arr2 = Object.entries(obj);
Run Code Online (Sandbox Code Playgroud)

...或者Object.keys如果您只想要属性名称,或者Object.values如果您只想要值。

当然,如果您愿意,您可以使对象可迭代:只需给它一个迭代器。例如:

const obj = {
  name: "doug",
  age: 234,
  profession: "seeker of Chthulhu"
};
const arr2 = Object.entries(obj);
console.log(arr2);
Run Code Online (Sandbox Code Playgroud)

您可以通过为它们定义适当的迭代器并Symbol.iterator在原型上提供-named 属性来使您创建的任何类的实例可迭代:

const obj = {
  name: "doug",
  age: 234,
  profession: "seeker of Chthulhu",
  * [Symbol.iterator]() {
    return yield* Object.entries(this);
  }
};
const arr2 = [...obj];
console.log(arr2);
Run Code Online (Sandbox Code Playgroud)

那就是它在某些情况下有效,但在其他情况下无效......

嗯,一般来说,传播符号就是如此。属性传播仅在对象初始值设定项中定义,并且仅在操作数是某种对象时才有效。(它的对应物,新的属性剩余符号,在解构赋值模式中定义。)可迭代扩展仅在数组初始值设定项和函数参数列表中定义,并且仅在其操作数是某种可迭代时才有效。(它的对应物,可迭代的休息符号,在创建数组的解构赋值模式中定义。)