泗县网站建设与推广培训,长春建站方法,河北省唐山市建设规划局的网站,grunt wordpress1. Iterator
1. JavaScript迭代器协议
在JavaScript中#xff0c;迭代器也是一个具体的对象#xff0c;这个对象需要符合迭代器协议#xff08;iterator protocol#xff09;#xff1a;
◼ 迭代器协议定义了产生一系列值#xff08;无论是有限还是无限个#xff09;…1. Iterator
1. JavaScript迭代器协议
在JavaScript中迭代器也是一个具体的对象这个对象需要符合迭代器协议iterator protocol
◼ 迭代器协议定义了产生一系列值无论是有限还是无限个的标准方式
◼ 在JavaScript中这个标准就是一个特定的next方法
next方法有如下的要求
◼ 一个无参数或者一个参数的函数返回一个应当拥有以下两个属性的对象
doneboolean
✓ 如果迭代器可以产生序列中的下一个值则为 false。这等价于没有指定 done 这个属性。
✓ 如果迭代器已将序列迭代完毕则为 true。这种情况下value 是可选的如果它依然存在即为迭代结束之后的默认返回值。
value
✓ 迭代器返回的任何 JavaScript 值。done 为 true 时可省略。
const names [abc, cba, nba]// 给数组names创建一个迭代器(迭代器: names的迭代器)
let index 0
const namesIterator {next: function() {// done: Boolean// value: 具体值/undefinedif (index names.length) {return { done: false, value: names[index] }} else {return { done: true }}}
}console.log(namesIterator.next())
console.log(namesIterator.next())
console.log(namesIterator.next())
console.log(namesIterator.next())// 数组nums
const nums [100, 24, 55, 66, 86]let indexNum 0
const numsIterator {next: function() {// done: Boolean// value: 具体值/undefinedif (indexNum nums.length) {return { done: false, value: nums[indexNum] }} else {return { done: true }}}
}2. 维数组创建一个迭代器函数
为数组生成迭代器封装函数优化
const names [abc, cba, nba]
const nums [100, 24, 55, 66, 86]// 封装一个函数
function createArrayIterator(arr) {let index 0return {next: function() {if (index arr.length) {return { done: false, value: arr[index] }} else {return { done: true }}}}
}const namesIterator createArrayIterator(names)
console.log(namesIterator.next())
console.log(namesIterator.next())
console.log(namesIterator.next())
console.log(namesIterator.next())const numsIterator createArrayIterator(nums)
console.log(numsIterator.next())
console.log(numsIterator.next())
console.log(numsIterator.next())
console.log(numsIterator.next())
console.log(numsIterator.next())
console.log(numsIterator.next())3. 创建可迭代对象
当一个对象实现了iterable protocol协议时它就是一个可迭代对象
这个对象的要求是必须实现 iterator 方法在代码中我们使用 Symbol.iterator 访问该属性
// 将infos变成一个可迭代对象
/*1.必须实现一个特定的函数: [Symbol.iterator]2.这个函数需要返回一个迭代器(这个迭代器用于迭代当前的对象)
*/
const infos {friends: [kobe, james, curry],[Symbol.iterator]: function() {let index 0const infosIterator {next: function() {// done: Boolean// value: 具体值/undefinedif (index infos.friends.length) {return { done: false, value: infos.friends[index] }} else {return { done: true }}}}return infosIterator}
}4. 可迭代对象的操作
JavaScript中语法for …of、展开语法spread syntax、yield*后面讲、解构赋值Destructuring_assignment
// 将infos变成一个可迭代对象
/*1.必须实现一个特定的函数: [Symbol.iterator]2.这个函数需要返回一个迭代器(这个迭代器用于迭代当前的对象)
*/
const infos {friends: [kobe, james, curry],[Symbol.iterator]: function() {let index 0const infosIterator {next: function() {// done: Boolean// value: 具体值/undefinedif (index infos.friends.length) {return { done: false, value: infos.friends[index] }} else {return { done: true }}}}return infosIterator}
}for (const item of infos) {console.log(item)
}创建一些对象时new Map([Iterable])、new WeakMap([iterable])、new Set([iterable])、new WeakSet([iterable]);
// 2.一些类的构造方法中, 也是传入的可迭代对象
const set new Set([aaa, bbb, ccc])
const set2 new Set(abc)
console.log(set2)
const set3 new Set(info)
console.log(set3)一些方法的调用Promise.all(iterable)、Promise.race(iterable)、Array.from(iterable);
const p1 Promise.resolve(aaaa)
const p2 Promise.resolve(aaaa)
const p3 Promise.resolve(aaaa)
const pSet new Set()
pSet.add(p1)
pSet.add(p2)
pSet.add(p3)
Promise.all(pSet).then(res {console.log(res:, res)
})5. 原生迭代器
String、Array、Map、Set、arguments对象、NodeList集合都是可迭代对象默认实现了[Symbol.iterator]函数
// 可迭代对象必然有一个[Symbol.iterator]函数
// 数组是一个可迭代对象
const students [张三, 李四, 王五]
console.log(students[Symbol.iterator])
const studentIterator students[Symbol.iterator]()
console.log(studentIterator.next())
console.log(studentIterator.next())
console.log(studentIterator.next())
console.log(studentIterator.next())6. 自定义类的迭代
在面向对象开发中我们可以通过class定义一个自己的类这个类可以创建很多的对象如果我们也希望自己的类创建出来的对象默认是可迭代的那么在设计类的时候我们就可以添加上 iterator 方法
class Person {constructor(name, age, height, friends) {this.name namethis.age agethis.height heightthis.friends friends}// 实例方法running() {}[Symbol.iterator]() {let index 0const iterator {next: () {if (index this.friends.length) {return { done: false, value: this.friends[index] }} else {return { done: true }}}}return iterator}
}const p1 new Person(why, 18, 1.88, [curry, kobe, james, tatumu])
const p2 new Person(kobe, 30, 1.98, [curry, james, aonier, weide])for (const item of p2) {console.log(item)
}7. 迭代器的中断
迭代器在某些情况下会在没有完全迭代的情况下中断 比如遍历的过程中通过break、return、throw中断了循环操作 比如在解构的时候没有解构所有的值
那么这个时候我们想要监听中断的话可以添加return方法
class Person {constructor(name, age, height, friends) {this.name namethis.age agethis.height heightthis.friends friends}// 实例方法running() {}[Symbol.iterator]() {let index 0const iterator {next: () {if (index this.friends.length) {return { done: false, value: this.friends[index] }} else {return { done: true }}},return: () {console.log(监听到迭代器中断了)return { done: true }}}return iterator}
}const p1 new Person(why, 18, 1.88, [curry, kobe, james, tatumu])for (const item of p1) {console.log(item)if (item kobe) {break}
}2. Generator
生成器是ES6中新增的一种函数控制、使用的方案它可以让我们更加灵活的控制函数什么时候继续执行、暂停执行等
1. 生成器函数
生成器函数也是一个函数但是和普通的函数有一些区别 首先生成器函数需要在function的后面加一个符号* 其次生成器函数可以通过yield关键字来控制函数的执行流程 最后生成器函数的返回值是一个Generator生成器
✓ 生成器事实上是一种特殊的迭代器
/*生成器函数: 1.function后面会跟上符号: *2.代码的执行可以被yield控制3.生成器函数默认在执行时, 返回一个生成器对象* 要想执行函数内部的代码, 需要生成器对象, 调用它的next操作* 当遇到yield时, 就会中断执行
*/// 1.定义了一个生成器函数
function* foo() {console.log(1111)console.log(2222)yieldconsole.log(3333)console.log(4444)yieldconsole.log(5555)console.log(6666)
}// 2.调用生成器函数, 返回一个 生成器对象
const generator foo()
// 调用next方法
generator.next()
generator.next()
generator.next()2. 生成器的参数和返回值
yield后面传入的参数是最后next后得到对象的value属性的值
// 1.定义了一个生成器函数
function* foo() {console.log(执行内部代码:1111)console.log(执行内部代码:2222)yield aaaaconsole.log(执行内部代码:3333)console.log(执行内部代码:4444)yield bbbbconsole.log(执行内部代码:5555)console.log(执行内部代码:6666)yield cccc
}// 2.调用生成器函数, 返回一个 生成器对象
const generator foo(next1)
// 调用next方法
console.log(generator.next()) // { done: false, value: aaaa }
console.log(generator.next()) // { done: false, value: bbbb }
console.log(generator.next()) // { done: false, value: cccc }
console.log(generator.next()) // {done: true, value: undefined}中间return会使得next()之后返回对象的done变为truevalue变为return的值
// 1.定义了一个生成器函数
function* foo() {console.log(执行内部代码:1111)console.log(执行内部代码:2222)yield aaaaconsole.log(执行内部代码:3333)console.log(执行内部代码:4444)return bbbbconsole.log(执行内部代码:5555)console.log(执行内部代码:6666)yield cccc
}// 2.调用生成器函数, 返回一个 生成器对象
const generator foo(next1)
// 调用next方法
console.log(generator.next()) // { done: false, value: aaaa }
console.log(generator.next()) // { done: true, value: bbbb }
console.log(generator.next()) // { done: true, value: undefined }
console.log(generator.next()) // { done: true, value: undefined }
console.log(generator.next()) // { done: true, value: undefined }generator.return()会直接结束迭代器
// 1.定义了一个生成器函数
function* foo() {console.log(执行内部代码:1111)console.log(执行内部代码:2222)yield aaaaconsole.log(执行内部代码:3333)console.log(执行内部代码:4444)yield bbbbconsole.log(执行内部代码:5555)console.log(执行内部代码:6666)yield cccc
}// 2.调用生成器函数, 返回一个 生成器对象
const generator foo(next1)
// 调用next方法
console.log(generator.next()) // { done: false, value: aaaa }
console.log(generator.return()) // { done: true, value: undefined }
console.log(generator.next()) // { done: true, value: undefined }
console.log(generator.next()) // { done: true, value: undefined }
console.log(generator.next()) // { done: true, value: undefined }执行的过程中传入参数
// 1.定义了一个生成器函数
function* foo(next1) {console.log(执行内部代码:1111, next1)console.log(执行内部代码:2222, next1)const next2 yield aaaaconsole.log(执行内部代码:3333, next2)console.log(执行内部代码:4444, next2)return bbbbconsole.log(执行内部代码:5555)console.log(执行内部代码:6666)yield cccc
}// 2.调用生成器函数, 返回一个 生成器对象
const generator foo(next1)
// 调用next方法
console.log(generator.next(next2))
console.log(generator.next(next3))generator.throw()会直接抛出异常但是需要捕获异常
3. 生成器替代迭代器
const names [abc, cba, nba]
const nums [100, 22, 66, 88, 55]function* createArrayIterator(arr) {for (let i 0; i arr.length; i) {yield arr[i]}// yield arr[0]// yield arr[1]// yield arr[2]// return undefined
}4. 生成器语法糖
这个时候相当于是一种yield的语法糖只不过会依次迭代这个可迭代对象每次迭代其中的一个值
class Person {constructor(name, age, height, friends) {this.name namethis.age agethis.height heightthis.friends friends}// 实例方法*[Symbol.iterator]() {yield* this.friends}
}