Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/457.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript生成器函数中的Set键_Javascript_Ecmascript 6_Functional Programming_Iterator_Generator - Fatal编程技术网

Javascript生成器函数中的Set键

Javascript生成器函数中的Set键,javascript,ecmascript-6,functional-programming,iterator,generator,Javascript,Ecmascript 6,Functional Programming,Iterator,Generator,大家好,我正在尝试找出如何在符号迭代器中设置键,这是我到目前为止的代码: 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]

大家好,我正在尝试找出如何在符号迭代器中设置键,这是我到目前为止的代码:

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
例如,我遇到的问题是: 应该打印迭代器.next()的调用

{"value": "James", "key": "name", "done": false}
但是我越来越

{"value": "James", "done": false}
我想以某种方式设置“键”,就像设置“值”一样

我查过了,但是我没有看到任何与此相关的文档

有什么想法吗

编辑

这个问题的用例基本上是将James对象转换为iterable对象,这与“如何”无关,因此我第一次尝试使用生成器,然后我意识到我需要以这种格式打印对象:

{ 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

如果要同时生成键和值,则需要生成一个包含两项的数组,例如

yield [key, this[key]];
那么对象上的
.value
将是一个键/值对

还请注意,此行为与您从ES2017中添加的新函数
Object.entries(james)
中获得的类似,只是它返回一个
数组

如果你想

.next()
要返回同时具有
完成
的对象,答案是不能使用生成器执行此操作。这不是生成器提供的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};
    },
  };
};

但它不再是迭代器,它只是您自己定义的自定义对象。

您不能这样做。ES6中迭代器的接口是不可更改的:

interface IteratorResult {
  done: boolean;
  value: any;
}
interface Iterator {
  next(): IteratorResult;
}
interface Iterable {
  [Symbol.iterator](): Iterator
}

发电机只能用它工作。无论你产生什么,它都将在
值中

我修改了@jack.the.ripper代码来使用Object.keys和接下来的arrow函数,所以我们可以利用它

const james = {
    name: 'James',
    height: `5'10"`,
    weight: 185
};

james[Symbol.iterator] = function (){
  const keys = Object.keys(this)
  return {
    next: () => {
      let key = keys.shift();
      return {value: this[key], 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

对iterator.next()的调用应该打印…
为什么?迭代器显式地产生
value/done
对象,您不能在那里有其他字段。感谢您的回复,但我需要有这个对象,当在next=>{“value”:“James”,“key”:“name”,“done”:false}上进行打印时,而不是嵌入键值pairb,但迭代器不是这样工作的,所以您宁愿遵循标准,或者你想要那个输出,因为你不能两者兼得。你也没有给出任何关于用例的信息,因此很难提供更多的指导。基本上,用例是将
james
对象变成一个可移植的对象,这与“如何”无关,但我的第一次尝试就像使用生成器一样,然后我意识到,我需要打印我之前提到的对象,我将尝试另一种方法让迭代器返回项对是迭代对象的标准方法。这就是为什么所有的ES*API都在实现该功能的
.entries()
函数上进行了标准化<代码>存在
数组
对象
映射
集合
的条目。您尚未说明为什么需要使用
.key
而不是数组。如果是因为您希望有时能够只迭代值,那么对于这两种情况,您可以使用两种不同类型的迭代器函数。@jack.the.ripper:如果您不遵循标准,那么像
for…of
Array.from
这样的事情将无法像您所期望的那样工作。