gpt4 book ai didi

javascript - 如果对象传播不是可迭代的,它如何工作?

转载 作者:数据小太阳 更新时间:2023-10-29 05:21:10 24 4
gpt4 key购买 nike

我正在学习传播的新用途。我意识到object spread 是一个 ES2018 提案。它以下列方式在 Node 10.5 中工作:

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

传播的一个有趣用途是将可迭代对象转换为数组。它适用于 map ,例如,为您提供一组值对数组

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

好的,我知道对象不可迭代(目前)。但是对象传播是否与可迭代传播不同?也就是说,它在某些情况下有效,但在其他情况下无效,人们应该意识到对象只能传播到对象中,而不能传播到数组中?还是我错过了大局?我正在尝试了解 spread 的新用途,并感谢您的启发....

最佳答案

But is object spreading some kind of different creature than iterable spreading?

是的。属性传播根本不使用迭代。它是新的主要语法,其运行时语义已定义 by the spec ,而不是在可迭代/迭代方面:

PropertyDefinition:...AssignmentExpression

  1. Let exprValue be the result of evaluating AssignmentExpression.
  2. Let fromValue be ? GetValue(exprValue).
  3. Let excludedNames be a new empty List.
  4. Return ? CopyDataProperties(object, fromValue, excludedNames).

Property spread 专门用于对象属性,没有像 iterable spread 那样对其进行额外的概括。 (也不是很明显会怎样。:-))

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

const arr2 = Object.entries(obj);

例子:

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

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

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

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

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

class ExampleList {
constructor() {
this.head = this.tail = null;
}

add(value) {
const entry = {value, next: null};
if (!this.tail) {
this.head = this.tail = entry;
} else {
this.tail = this.tail.next = entry;
}
}

* [Symbol.iterator]() {
for (let current = this.head; current; current = current.next) {
yield current.value;
}
}
}

const list = new ExampleList();
list.add("a");
list.add("b");
list.add("c");

for (const value of list) {
console.log(value);
}

That is it will work in some circumstances but not others...

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

关于javascript - 如果对象传播不是可迭代的,它如何工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51084725/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com