本章涉及:
- 了解迭代器
- 了解可迭代对象
- 了解两种协议:
迭代器协议
和可迭代协议
- 了解JS中的部分语法的实现原理
迭代器
在 JavaScript 中,迭代器是一个对象,它定义一个序列,并在终止时可能返回一个返回值。
迭代器是一个对象
,该对象需要符合迭代器协议(iterator protocol)
何为迭代器协议?
迭代器协议
简单的说,该对象必须包含一个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)
,跟上面的迭代器协议不一样。
可迭代协议
一个对象必须实现 @@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
、结构解析
、生成器
、展开语法
、Map
、Set
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的原理