Javascript 如果对象不是iterable,它是如何工作的?

Javascript 如果对象不是iterable,它是如何工作的?,javascript,ecmascript-6,javascript-objects,Javascript,Ecmascript 6,Javascript Objects,我正在学习传播的新用途。我意识到对象传播是ES2018提案。它在节点10.5中的工作方式如下: const oldObj = {name:"doug", age:34}; const newObj = {...oldObj}; console.log(newObj); // { name: 'doug', age: 34 } 扩展的一个有趣用途是将可重用数据转换为数组。例如,它可以很好地处理映射,为您提供一个值对数组数组 const mappie = new Map().set("name"

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

const oldObj = {name:"doug", age:34};
const newObj = {...oldObj}; 
console.log(newObj); // { name: 'doug', age: 34 }
扩展的一个有趣用途是将可重用数据转换为数组。例如,它可以很好地处理映射,为您提供一个值对数组数组

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' ] ]
但我不能在物体上使用这个

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

const arr2 = [...obj];
console.log(arr2);
给我

TypeError: obj is not iterable
好的,我知道现在这个对象是不可移植的。但是,物体传播和它的传播是不同的吗?也就是说,它在某些情况下有效,但在其他情况下无效。人们应该认识到,对象只能传播到对象中,而不能传播到数组中?还是我错过了大局?我正试图了解传播的新用途,任何启示都值得欣赏

但是,物体传播和它的传播是不同的吗

对。属性排列根本不使用迭代。这是一种新的主要语法,其运行时语义是定义的,而不是根据可重用/迭代:

PropertyDefinition:…AssignmentExpression

  • 让exprValue作为赋值表达式求值的结果
  • 让价值成为现实吧?GetValue(导出值)
  • 让excludedNames成为一个新的空列表
  • 返回?CopyDataProperties(对象、fromValue、excludedNames)
  • 属性扩展是专门针对对象属性的,没有像iterable扩展那样的额外泛化。(也不清楚会发生什么。:-)

    对于您的
    常量arr2=[…obj]用例,您可能需要:

    例如:

    const obj={
    姓名:“道格”,
    年龄:234,
    职业:“Chthulhu的探索者”
    };
    const arr2=对象条目(obj);
    
    控制台日志(arr2) < P > T.J. Crowder的答案是正确的,但是这对于注释来说太长了,希望能给你更好的理解实用性:考虑频繁的情况,你想要从对象中得到两个属性并把它们放在一个新的对象中。一些第三方库(如Ramda和lodash)实现了实现此功能的实用程序函数,但通过结合速记属性、分解结构和对象扩展,可以在vanilla JS中简洁地完成:

    const foo = { a: 1, b: 2, c: 3, d: 4 };
    const { a, d } = foo;
    const bar = { a, d };
    console.log(bar); // { a: 1, d: 4 }
    
    如果您不介意滥用逗号运算符,可以进一步缩短:

    let a, d, bar, foo = { a: 1, b: 2, c: 3, d: 4 };
    bar = ({a, d} = foo, {a, d});
    

    或者
    Symbol.iterator
    尚未为对象实现。@NinaScholz-不是,也不太可能是。@t.J.Crowder--谢谢,谢谢你的代码片段。当你说“属性扩展”(和“属性休息”)时,你是在说专门应用于对象的扩展和休息吗?(我对术语不熟悉,尽管我去看了你链接到的规格,但我现在有点不知所措)。那么,可以公平地说,集合的扩展确实通过iterable工作,但对于对象,它只是一些不同的东西——一个“属性扩展”?@NinaScholz——即使定义了
    Object.prototype[Symbol.iterator]
    ,它也不会被属性扩展使用,只是iterable扩展()。(就个人而言,我对此表示怀疑。如果你想要一个对象属性的可移植版本,你可以使用
    object.entries
    )“但是对象传播的是某种不同于可移植传播的生物吗?”-是的,绝对是。它们甚至没有以相同的语言版本介绍。如果下面的任何答案回答了您的问题(堆栈溢出的工作方式),您可以通过单击旁边的复选标记来“接受”答案。但前提是你的问题得到了回答;如果没有,考虑在问题中添加更多的细节。
    let a, d, bar, foo = { a: 1, b: 2, c: 3, d: 4 };
    bar = ({a, d} = foo, {a, d});