我正在尝试理解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 });
这可以按预期工作(自定义迭代器 - thank you):
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(…)
为什么以及如何重现原生数组的行为?
答案 0 :(得分:5)
因为<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="work-row">
<div class="work-piece">
<div>
<h3 class="project-name">Guess the Shape</h3>
</div>
</div>
<!--
-->
<div class="divider-column"></div>
<!--
-->
<div class="work-piece"></div>
<!--
-->
<div class="divider-column"></div>
<!--
-->
<div class="work-piece"></div>
</div>
返回一个以迭代器为键的对象。所以你可以使用dogsNames()
而不是dogNames,但要直接访问for...of
,你需要访问在对象上声明的迭代器函数,如下所示:
next()
为了完整性,共享next()函数的完整代码:
dogsNames()[Symbol.iterator]().next()
答案 1 :(得分:4)
dogNames
必须返回一个迭代器(实现next
方法的东西),它也是一个可迭代的(实现Symbol.iterator
方法的东西)(并返回它自己)。 Every built-in iterator does that
快速测试验证:
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};
},
};
};