迭代器
可迭代对象和迭代器是ES6的一个特性,迭代器可使用 for/of 进行迭代
for(let i of [1, 2, 3]){ console.log(i); }迭代器可使用扩展操作符,也可进行解构
let chars = [..."abcde"] // ["a", "b", "c", "d", "e"] let o = {a:1, b:2, c:3, d:4} let {a, b, c, d} = o可迭代对象的迭代器方法使用了符号 Symbol.iterator 作为名字,重复调用使用next()方法,next()方法会返回一个迭代结果对象,该结果对象有两个属性,value,done,value代表值,done代表是否停止,当done为true时,就意味着到了末尾,下列代码等同于 for/of
let iterable = [99, 100] let iterator = iterable[Symbol.iterator]() for(let result = iterator.next(); !result.done; result = iterator.next()){ console.log(result.value) }
自定义一个可迭代的类
创建一个可迭代的集合类class Range{ constructor(from, to){ this.from = from this.to = to } has(x){ return typeof x === "number" && this.from <= x <= this.to} toString() { return `{x| ${this.from} <= x <= ${this.to} }`} [Symbol.iterator](){ let next = Math.ceil(this.from) // 向上取整,小数部分舍去,整数部分加1 let last = this.to return { next(){ return next <= last? {value:next++, done:false}: {done:true} }, [Symbol.iterator](){return this} } } } for(let i of new Range(0, 10)){ console.log(i) }
迭代器的惰性
迭代器又叫惰性器,可以让需求一步一步进行,比如字符串的split()方法,哪怕一个单词都没有使用,也要全部处理完保存在数组中,此时就可用迭代器一步一步进行处理function words(s){ let r = /\s+|$/g // 匹配一个或多个空格或末尾 r.lastIndex = s.match(/[^ ]/).index // 开始匹配第一个非空格 return { // 返回一个可迭代的迭代器对象 [Symbol.iterator](){ return this }, next(){ let start = r.lastIndex // 从上次匹配结束的地方恢复 if(start < s.length){ // 如果好美处理完 let match = r.exec(s) // 匹配下一个单词的边界 if(match){ // 如果找到了一个单词,返回 return { value: s.substring(start, match.index)} } } return { done: true } // 否则返回表示处理完成的结果 } } } [...words("abc def ghi")] // [ 'abc', 'def', 'ghi' ]