了解实现自定义迭代器
Understanding implementing custom iterators
我试图理解 Ecmascript 6 迭代器,并试图创建一个行为与本机数组非常相似的数据结构。
for (let i of [1,2,3]) console.log(i); //Iterate over data set itself
将输出1,2,3
for (let i of [1,2,3].keys()) console.log(i); //Iterate over a custom iterator from a method
将输出0,1,2
,并且
var a = [1,2,3];
var keys = [...a.keys()];
将按预期包含[0,1,2]
。
因此
console.log([1,2,3].keys().next());
将输出Object {value: 0, done: false}
现在,我创建了一种新的数据类型,并尝试使其以相同的方式运行。
var myDogs = function(dogs) {
this.dogs = dogs;
this[Symbol.iterator] = () => {
let i = -1;
return {
next() {
i++;
var dog = Object.keys(dogs)[i];
if (!dog) return {done:true};
return {value:{ dog, hungry:dogs[dog] }, done:false};
}
};
};
this.dogsNames = () => {
return {
[Symbol.iterator]() {
let i = -1;
return {
next() {
i++;
var dog = Object.keys(dogs)[i];
if (!dog) return {done:true};
return {value: dog, done:false};
}
};
}
}
}
};
var dogs = new myDogs({ buddy: true, hasso: false });
这按预期工作(自定义迭代器 - 谢谢):
var dogHungryMap = [...dogs];
dogHungryMap == [{ dog: 'buddy', hungry: true }, { dog: 'hasso': hungry: false }]
迭代器dogsNames()
几乎按预期工作。这没关系:
var names = [...dogs.dogsNames()];
names == ["buddy", "hasso"]
但这不会:
dogs.dogsNames().next()
VM19728:2 Uncaught TypeError: dogs.dogsNames(...).next is not a function(…)
为什么以及如何重现本机数组的行为?
因为dogsNames()
返回一个以迭代器作为键的对象。所以你可以使用 for...of
over dogsNames,但要直接访问next()
你需要访问在对象上声明的迭代器函数,如下所示:
dogsNames()[Symbol.iterator]().next()
巴别塔 REPL 示例
为了完整起见,共享 next() 函数的完整代码:
var myDogs = function(dogs) {
this.dogs = dogs;
let i = -1;
var iter = {
next() {
i++;
var dog = Object.keys(dogs)[i];
if (!dog) return {done:true};
return {value:{ dog, hungry:dogs[dog] }, done:false};
}
}
this[Symbol.iterator] = () => iter;
this.next = iter.next;
};
var dogList = new myDogs({
dog1: "no",
dog2: "yes"
});
for(const x of dogList) console.log(x);
console.log(dogList.next());
console.log(dogList.next());
dogNames
必须返回一个迭代器(实现next
方法的东西),该迭代器也是一个可迭代的(实现Symbol.iterator
方法的东西)(并返回自身)。每个内置迭代器都这样做。
快速测试可验证:
var it = [].keys();
it[Symbol.iterator]() === it // true
因此,您可以将代码更改为
this.dogsNames = () => {
let i = -1;
return {
[Symbol.iterator]() {
return this;
},
next() {
i++;
var dog = Object.keys(dogs)[i]; // should probably also be put in the outer function
if (!dog) return {done:true};
return {value: dog, done:false};
},
};
};
相关文章:
- jQuery工具验证器自定义效果-添加&消除影响
- Babel编译错误:找不到模块核心js/library/fn/get迭代器
- 从JSON API结果迭代时未定义
- 从两个基于0的for循环迭代器中获取单个基于0的索引的公式
- Rails:试图在javascript(Google Charts API)中嵌入一个adv-ruby(each+迭代器
- 在javascript中,从迭代器创建Array
- Javascript中的迭代器和生成器
- 从迭代器/生成器中获取单个yield值
- 迭代器和可迭代之间的区别
- 文件夹迭代器中的Google驱动器文件迭代器
- DOM:如何根据迭代器值设置元素宽度并在mouseover上调用函数
- javascript中多维数组的迭代器
- 迭代Promise迭代器的非递归方法
- 循环中的Node.js回调具有错误的迭代器值
- underscore.js,迭代器引用错误
- 去掉foreach中的自定义绑定以获取迭代器
- 将自定义迭代器添加到 JavaScript 类
- 了解实现自定义迭代器
- 为什么我们要定义符号.[Symbol]的迭代器.迭代器)?javascript中的可迭代对象
- 将数组迭代到自定义网格中