JS系列:认识迭代器和可迭代对象

本章涉及:

  • 了解迭代器
  • 了解可迭代对象
  • 了解两种协议:迭代器协议可迭代协议
  • 了解JS中的部分语法的实现原理

迭代器

在 JavaScript 中,迭代器是一个对象,它定义一个序列,并在终止时可能返回一个返回值。

迭代器是一个对象,该对象需要符合迭代器协议(iterator protocol)

何为迭代器协议?

迭代器协议

MDN迭代器协议

简单的说,该对象必须包含一个next() 方法

  • 参数:一个无参数或者一个参数的函数
  • 返回值:返回一个对象,包含done(Boolean)value(any) 属性

done属性解释:

如果迭代器可以产生序列中的下一个值,则为 false。(这等价于没有指定 done 这个属性。)

如果迭代器已将序列迭代完毕,则为 true。这种情况下,value 是可选的,如果它依然存在,即为迭代结束之后的默认返回值。

根据上面的条件

const obj = {
    next: function() {
        return {done: false, value: 321321}
    }
}

这里obj就是一个迭代器。

迭代器的练习

// 针对数组创建一个迭代器(数组本身自带迭代器)
function createArrayIterator(arr) {
    let index = 0;
    // 迭代器是一个对象,返回一个对象,对象中包含next方法
    return {
        next: function() {
            if(index < arr.length) {
                return {done: false, value: arr[index++]}
            } else {
                return {done: true, value: undefined}
            }
        }
    }
}

let arr = [12, 43, 44]
const iterator = createArrayIterator(arr)
console.log(iterator.next());      // { done: false, value: 12 }
console.log(iterator.next());      // { done: false, value: 43 }
console.log(iterator.next());      // { done: false, value: 44 }
console.log(iterator.next());      // { done: true, value: undefined }

可迭代对象

定义: 是一个对象,该对象需要满足 可迭代协议(iterrable protocol) ,跟上面的迭代器协议不一样。

可迭代协议

MDN可迭代协议

一个对象必须实现 @@iterator 方法。这意味着对象(或者它原型链上的某个对象)必须有一个键为 @@iterator 的属性,可通过常量 Symbol.iterator 访问该属性。

其中Symbol.iterator 是一个函数,返回一个迭代器(上面说到)

根据上面的条件

const obj = {
    names: ['james', 'kobe', 'curry'],
    // 是一个函数,返回一个迭代器
    [Symbol.iterator]: function() { 
        let index = 0;
        return {
            // 使用箭头函数,是this指向obj
            next: () => {
                if(index < this.names.length) {
                    return {done: false, value: this.names[index++]}
                } else {
                    return {done: true, value: undefined}
                }
            }
        }
    }
}

原生迭代器对象

  • string
  • Array
  • arguments (函数参数)
  • Map
  • Set
  • NodeList (DOM结构)
let arr = [12, 43, 44]
console.log(arr[Symbol.iterator])    // [Function: values]

迭代器的应用

  • javaScript: for..of结构解析生成器展开语法MapSet

for...of实现的原理

let arr = [12, 43, 44]
for(let item of arr) {
    console.log(item) 
}
// 上面会依次打印出value值  12,43,44

这里就主要是使用的 迭代器

const iterator = arr[Symbol.iterator]
// for ... of 每次执行的时候,就会调用next方法
const obj  = iterator.next()
if(!obj.done) {
    // 输入 obj.value
} else {
    // 结束循环
}

小结:

1、遍历对象的时候,就会报错xxx is not iterable

2、结构解析展开语法 都是调用的 next()方法,拿取value值。

3、对象也可以使用结构解析展开语法,这是ES9(2018)新的语法,是JS引擎内部实现的,不是iterator的原理

你可能感兴趣的:(javascript)