目录
1、Symbol()
2、迭代器生成器
执行流程
模拟生成器函数
for of 遍历迭代选择器
yield *
Generator函数应用
1、Symbol()
Symbol表示独一无二的值
const s1 = Symbol('a')
const s2 = Symbol('a')
console.log(s1 === s2) // false
console.log(typeof s1) // 'symbol'
应用场景-产生独一无二的值
let symbol=Symbol()
o[symbol]=100
console.log(o)//{a: 20, b: 30, c: 40, Symbol(): 100}
2、迭代器生成器
Generator是一个特殊的函数,执行它会返回一个lterator对象。通过遍历迭代器, Generator函数运行后会返回一个遍历器对象,而不是普通函数的返回值。
普通函数一旦执行 函数体从上往下依次执行
function f(){
console.log(1)//1
console.log(2)//2
console.log(3)//3
}
f()
生成器函数(generator)----生成迭代器(Iterator)的函数,配合yield关键字来控制代码执行流程
next(参数) 赋值给上一次yield
yield后面的表达式作为本次next返回值的value属性值
it.next() 执行下一步
function* go(str){
// console.log(1)
let a=yield str
// console.log(2)
let b=yield a
// console.log(3)
return b
}
const it=go('hello')// it拿到生成器函数返回值
console.log(it)//go {<suspended>}
const r1=it.next(1)
console.log(r1)//{value: 'hello', done: false}
const r2=it.next(2)
console.log(r2)//{value: 2, done: false}
const r3=it.next(3)
console.log(r3)//{value: 3, done: true}
执行流程
function* test(num){
let x=3*(yield num+1)
let y=yield x/3
return x+y+num
}
let n=test(3)
console.log(n.next())//{value: 4, done: false}
console.log(n.next(5))//{value: 5, done: false}
console.log(n.next(8))//{value: 26, done: true}
/* test(3) 拿到迭代器,3传给num
第一次 n.next() ,函数开始执行,遇到第一个yield停下来,把yield后面的表达式值作为next方法的返回值中value属性值
第二次 n.next(5) 函数继续执行,5赋值给上一次yield整体, x = 3 * 5,又遇见yield 5 ,把yield后面的表达式值作为next方法的返回值中value属性值
第三次 n.next(8) 函数继续执行 8赋值给上一次yield整体,y = 8 ,返回15+8 + 3 ,函数执行完毕,把返回值赋值给next方法的返回值中value属性值*/
模拟生成器函数
//模拟生成器函数
function buy(books) {
let i = 0
return {
next() {
let done = i === books.length ? true : false
let value = done ? undefined: books[i++]
return {
value,
done,
}
},
}
}
// function* buy(books){
// // yield books[0]
// // yield books[1]
// for(let i=0;i<books.length;i++){
// yield books[i]
// }
// }
const it = buy(['js', 'vue'])
console.log(it.next())//{value: 'js', done: false}
console.log(it.next())//{value: 'vue', done: false}
console.log(it.next())//{value: undefined, done: true}
for of 遍历迭代选择器
<script>
function* demo(){
yield 1
yield 2
yield 3
yield 4
}
const it =demo()
for(let k of it){
console.log(k)//1,1,3,4
}
</script>
yield *
yield *可以在Generator函数内部调用一个Generator函数
<script>
function* test() {
yield 'a ';
yield 'b ';
}
function* test1() {
yield 'x ';
yield* test();
yield 'y'
}
for (let v of test1()) {
console.log(v);
}
//相当于
// function* test() {
// yield 'a ';
// yield 'b ';
// }
// function* test1() {
// yield 'x ';
// for (let v of test()) {
// console.log(v);
// }
// yield 'y ';
// }
// for (let v of test1()) {
// console.log(v);
// }
</script>
Generator函数应用
需求:实现点击一下切换图片,两张图片来回切换
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
img{
width: 200px;
height: 200px;
}
</style>
</head>
<body>
<img src="./1.jpg" alt="">
<button>切换</button>
<script>
const Img=document.querySelector('img')
const btn=document.querySelector('button')
//以前的方法
// let flag=true
// btn.addEventListener('click',function(){
// if(flag){
// Img.src='./1.jpg'
// flag=false
// }else{
// Img.src='./2.jpg'
// flag=true
// }
// })
//generator应用
function* change(){
while(true){//来回切换是一个死循环
yield ( Img.src='./1.jpg')
yield ( Img.src='./2.jpg')
}
}
const it=change()
btn.addEventListener('click',function(){
it.next()
})
</script>
</body>
</html>