如何将一个对象转化为可迭代的呢?
首先,先了解什么是可迭代的
具有迭代器的数据类型是可迭代的。
那么什么是迭代器?
迭代器:
是一种用于遍历的统一机制,这种机制允许我们调用next()方法,每次调用都会返回一个对象 {value,done},当完成迭代后done值为true,value为每次获取的元素。
谁又具有迭代器?
Array;Set;Map;String;类数组对象:Arguments;NodeList…
思路一:
因为普通对象没有迭代器,那么,只需要让普通对象拥有迭代器就可以了。
这里将数组中的迭代器(iterator)赋给了对象,默认为遍历value的迭代器。
let obj = {"0":"tom","1":"jerry","2":"terry",length:3};
//其中length属性必须有,不然不能迭代出来
obj[Symbol.iterator] = [][Symbol.iterator]; //此时obj就有了数组的迭代器
let values = obj[Symbol.iterator]();
value.next() //{value:"tom",done:false}
value.next() //{value:"jerry",done:false}
value.next() //{value:"terry",done:false}
Symbol():
这个函数可以产生一个特殊符号,这个符号可以用于key,通过这个key找见对应的函数。这个key好处在于它是隐式的,不会将它遍历出来。
优点:代码简单,便于理解。
缺点:主动性差,没有自主。
思路二:
既然普通对象没有迭代器,而将其他具有迭代器的赋给对象又没有主动性,那么何不如自己封装一个迭代器,这样就可以按照自己想要的功能来设计迭代器,拥有高主动性。
- 想要封装迭代器,那么必须了解的是Generator函数
Generator函数可以用于调用异步函数,将异步操作同步化,返回值是一个迭代器对象。 - this
Generator与普通函数中的this的获取是一致的 - yeild表达式的返回值
- 默认是没有返回值的
- iterator.next(参数)
当前这个参数为上一个yield表达式的返回值
let obj = {"0":"tom","1":"jerry","2":"terry"};
//封装了一个keys迭代器
function* keys() {
for(let key in this) {
yield key;
}
}
//封装了一个values迭代器
function* values() {
for(let key in this) {
let val = this[key];
yield val;
}
}
//封装了一个entries迭代器
function* entries() {
for(let key in this) {
let val = this[key];
yield [key,val];
}
}
//调用
obj[Symbol.iterator] = entires;
let entry = obj[Symbol.iterator]();
entry.next() //{value:["0","tom"],done:false}
entry.next() //{value:["1","jerry"],done:false}
entry.next() //{value:["2","terry"],done:false}
优点:主动性强,可以根据自己的意愿来获取所需的迭代器。