您好我想弄清楚如何在符号迭代器中设置密钥,这是我到目前为止的代码:
let james = {
name: 'James',
height: `5'10"`,
weight: 185
};
james[Symbol.iterator] = function* () {
for (let key in this) {
yield this[key];
}
}
let iterator = james[Symbol.iterator]();
console.log(iterator.next().value); // 'James'
console.log(iterator.next().value); // `5'10`
console.log(iterator.next().value); // 185
我遇到的问题是: iterator.next()的调用应该打印
{"value": "James", "key": "name", "done": false}
但我正在
{"value": "James", "done": false}
我想以某种方式设置"键"就像我设置"值"。
一样我查看了documentation,但我还没有看到任何与此相关的文档。
有什么想法吗?
修改
问题的用例基本上是将 James对象转换为可迭代对象,它并不重要"如何",所以我的第一次尝试是使用生成器,然后我意识到我需要以这种格式打印对象:
{ value: 'James', key: 'name', done: false }
{ value: '5\'10"', key: 'height', done: false }
{ value: 185, key: 'weight', done: true }
这不是一种标准的方法,所以我必须创建一个自定义方法来实现"行为:
感谢@loganfsmyth指出我正确的方向,我提出了这个简单的解决方案:let james = {
name: 'James',
height: `5'10"`,
weight: 185
};
james[Symbol.iterator] = function (){
const keys = [];
for (let key in this) {
keys.push({'key':key, 'value':this[key]});
}
return {
next(){
let {key,value} = keys.shift();
return {value,key,done:keys.length===0};
}
}
}
let iterator = james[Symbol.iterator]();
console.log(iterator.next().value); // 'James'
console.log(iterator.next().value); // `5'10`
console.log(iterator.next().value); // 185
答案 0 :(得分:3)
如果要同时生成键和值,则需要生成包含两个项的数组,例如
yield [key, this[key]];
然后对象上的.value
将成为键/值对。
另请注意,此行为类似于您从Object.entries(james)
获得的内容,这是ES2017中添加的新功能,但它返回Array
。
如果明确要
.next()
要返回同时包含key
,value
和done
的对象,那么答案是您无法使用生成器执行此操作。这不是生成器提供的API,也不是ES6中定义的迭代器协议,所以你不应该使用迭代器来尝试这样做。
你当然可以
james.makeCustomThing = function(){
const pairs = [];
for (const key in this) pairs.push([key, this[key]]);
return {
next(){
if (pairs.length === 0) return {done: true};
let [key, value} = pairs.shift();
return {key, value, done: false};
},
};
};
但是它不再是迭代器了,它只是你自己定义的一个自定义的东西。
答案 1 :(得分:2)
你无法做到。 ES6中迭代器的接口是不可更改的:
interface IteratorResult {
done: boolean;
value: any;
}
interface Iterator {
next(): IteratorResult;
}
interface Iterable {
[Symbol.iterator](): Iterator
}
发电机只能使用它。无论你产生什么,它都会在value
。
答案 2 :(得分:1)
我修改了@ jack.the.ripper代码以使用Object.keys,然后修改了箭头函数,所以我们可以使用它。
let buttons = document.getElementById("show-cart");
buttons.addEventListener("click", function (event) {
let name = event.target.getAttribute("data-name");
if (event.target.className === "delete") {
removeItemFromCartAll(name);
displayCart();
} else if (event.target.className === "minus") {
removeItemFromCart(name);
displayCart();
} else if (event.target.className === "plus") {
addItemToCart(name, 0, 1);
displayCart();
}
});