• 【es6】教程 Symbol数据以及迭代器和生成器


    知识点1,Symbol的介绍与创建

    常见6种数据类型,undefined,string,object,null,number,boolen
    es6新的数据类型,类似于字符串的数据类型
    symbol的值是唯一的,用来解决命名冲突的问题
    不能与其他数据进行运算,例如,比大小,拼接,加减,自增,自减

    //创建Symbol,方式一
    //每个从 Symbol() 返回的 symbol 值都是唯一的
    let s =Symbol()
    console.log(s,typeof s)//Symbol() "symbol"
    //创建Symbol,传入字符串,字符串作为描述字符串,相当于注释
    let s =Symbol('阿胜')
    let s1 =Symbol('阿胜')
    console(s===s1)//false,描述字符串只是标志,虽然标志相同,但编号不同
    
    
    //Symbol.for创建
    //Symbol.for()方法创建的 symbol 会被放入一个全局 symbol 注册表中
    //Symbol.for() 并不是每次都会创建一个新的 symbol,它会首先检查给定的 key 是否已经在注册表中了。假如是,则会直接返回上次存储的那个。否则,它会再新建一个
    let s2 =Symbol.for('阿胜')
    let s3 =Symbol.for('阿胜')
    console.log(s2)//Symbol(阿胜)
    console(s2===s3)//true
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    知识点2,向对象添Symbol类型的属性

    >安全快速的将方法加到对象上面,不会破坏原有属性
    
    • 1
    let oldobject={
    	name:'2',
    	[Symbol('up')]:function(){
    		console.log('打印1')
     	}
    }
    
    console.log(oldobject)
    
    //内置属性
    const arr =[1,2,3]
    const arr2 =[4,5,6]
    arr2[Symbol.isConcatSpreadable]=false
    //这个是布尔值的,设置false,arr2作为整体拼接,设置true,展开拼接
    console.log(arr.concat(arr2))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    在这里插入图片描述

    知识点3,迭代器,Iterator

    1.迭代器,是一种接口,为各种不同的数据结构提供统一的访问机制,任何数据只要部署Iterator接口,就可以完成遍历操作
    2.es6创建了一种新的遍历命令for…of循环,Iterator主要供for—of使用
    3.Iterator接口,就是对象里边的属性,
    4.具备迭代器属性的属性:Array,Arguments,set,map,string,TypedArray,NodeList
    5.实际上就是因为Symbol的iterator属性
    在这里插入图片描述

    const arr =[1,2,3]
    //使用for...of遍历数组,输出键值1,2,3
    for(let i of arr){
    	console.log(i)
    }
    //使用for...in遍历数组,输出键0,1,2
    for(let i in arr){
    	console.log(i)
    }
    
    
    //原理
    //arr[Symbol.iterator],可以获取到
    //创建一个指针对象,指向当前数据结构的起始位置
    let iterator =arr[Symbol.iterator]();
    console.log(iterator)
    //第一次调用next方法,指针自动指向第一个成员,每次调用next方法,都会返回一个包含value和done属性的对象
    console.log(iterator.next())//{value: 1, done: false}
    //接下来不断调用next方法,指针一直往后移动,直到指向最后一个成员
    console.log(iterator.next())//{value: 2, done: false}
    console.log(iterator.next())//{value: 3, done: false}
    console.log(iterator.next())//{value: undefined, done: true}
    //value:数据域,done:指针域,
    //done为true表示遍历或者循环已完成
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    案列:实现自定义的遍历数组

    const obj = {
    				name: "大威天龙",
    				stuts: [9, 8, 7, 6, 5],
    				[Symbol.iterator]() {
    					let index = 0
    					//保存之前this
    					let that = this
    				 	//首先得有返回值
    					return {
    						//必须得有next方法
    						next: function() {
    							//next方法里面必须得返回一个包含value和done属性的对象
    							//注意,这里的this指向next方法,指不到外面数组,得声明一个变量保存之前this
    							if (index < that.stuts.length) {
    								let objk={
    									value: that.stuts[index],
    									done: false
    								}
    								//下标自增
    								index++
    								return objk
    								
    							} else {
    								return {
    									value: that.stuts[index],
    									done: true
    								}
    							}
    						}
    					}
    				},
    	}
    	//如果你想要循环obj,就必须自己写迭代器,实现自定义的遍历里面的数组
    	for (let i of obj) {
    		console.log(i)
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    知识点4,生成器-函数

    1.生成器函数是es6提供的一种异步编程的解决方案
    2.异步编程,之前是纯回调函数,形成回调地狱

    //生成器函数的声明方式
    		function * func(){
    			console.log("hello generator")
    		}
    			let funax=func()
    			console.log(funax)//标注1
    			//要想打印生成器里的语句,可以通过调用里面的next方法
    			console.log(funax.next())//hello generator
    		},
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    在这里插入图片描述

    yield 函数分割符
    1,只能在Generator函数内部使用
    2,运行.next(),遇到一个yield命令,就暂停
    3, .next()的返回值表示一个状态{value,done}
    4, 再运行.next(),从之前遇到的那个yield [表达式]处(后)继续恢复运行
    5,当.next()传参的时候,yield [表达式]整个被替换为传入的参数。
    	function* func() {
    				// console.log("步骤1")
    				yield '步骤一';
    				// console.log("步骤2")
    				yield '步骤二';
    				// console.log("步骤3")
    				yield '步骤三';
    				// console.log("步骤4")
    			}
    			//调用生成器函数
    			let funax = func()
    			funax.next()//步骤1
    			console.log(funax.next())//{value: '步骤二', done: false}
    			funax.next()//步骤3
    			funax.next()
    			funax.next()
    			//打印生成器的yield值
    			for( let v of func()){
    				console.log(v)
    			}
    			//步骤一
    			//步骤二
    			//步骤三
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    生成器函数的参数传递

    		//整体函数传参
    		function* func(x) {
    				console.log(x)//传参喽
    				yield '步骤一';
    				yield '步骤二';
    				yield '步骤三';
    			}
    			let funax = func("传参喽")
    			console.log(funax.next())//{value: '步骤一', done: false}
    			console.log(funax.next('哈哈哈'))//{value: '步骤二', done: false}
    
    			//next()方法可以传人实参,参数将作为上一个yield语句 的返回结果
    			//生成生成器函数
    			function* func(x) {
    				let one=yield '步骤一';
    				console.log(one,"1")//第一次 1
    				let two=yield '步骤二';
    				console.log(two,"2")//第二次 2
    				let three=yield '步骤三';
    				console.log(three,"3")
    			}
    			//调用生成器函数
    			let funax = func()
    			//注意,因为.next()方法作为上一个yield语句的返回结果
    			//所以,这里得先调用一遍,否则如下,哈哈哈没有传参过去
    			console.log(funax.next('哈哈哈'))//{value: '步骤一', done: false}
    			console.log(funax.next("第一次"))//{value: '步骤二', done: false}
    			console.log(funax.next("第二次"))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    生成器函数实例

    1秒后输出111,2秒后输出222,三秒后输出333

    	//旧方法,定时器的不断套用,形成回调地狱
    	function two() {
    		setTimeout(() => {
    			console.log(111)
    			setTimeout(() => {
    				console.log(222)
    				setTimeout(() => {
    					console.log(333)
    				}, 3000)
    			}, 2000)
    		}, 1000)
    	}
    	two()
    	//新方法,生成器函数
    			function one() {
    				setTimeout(() => {
    					console.log(111)
    					funx.next();
    				}, 1000)
    				
    			}
    
    			function two() {
    				setTimeout(() => {
    					console.log(222)
    				}, 2000)
    			}
    
    			function three() {
    				setTimeout(() => {
    					console.log(333)
    				}, 3000)
    			}
    			//生成生成器函数
    			function* func() {
    				yield one();
    				yield two();
    				yield three();
    			}
    			//调用生成器函数
    			let funx = func()
    			funx.next();///111
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    生成器函数实例二

    模拟获取各项数据,在没有获取到用户数据的时候,订单数据不能获取

    		function one() {
    				setTimeout(() => {
    					let data = '用户数据'
    					console.log(data) //此时那到底的data无法在下面进行操作
    					funx.next(data); //这里第二次调用传第一次的结果值,打开大门把看到的告诉生成器反馈信息
    				}, 1000)
    		}
    		function two() {
    				setTimeout(() => {
    					let data = '订单数据'
    					funx.next(data); //这里第三次调用传第二次的结果值
    				}, 1000)
    		}
    		function three() {
    				setTimeout(() => {
    					let data = '反馈数据'
    				}, 1000)
    		}
    			//生成生成器函数
    		function* func() {
    				let onedata = yield one();
    				//这里将第二次调用传来的第一次的结果值接收,进行操作,上面打开大门后有反馈信息,这里接收
    				let twodata =yield two();
    				//这里将第三次调用传来的第二次的结果值接收,进行操作
    				yield three();
    		}
    			//调用生成器函数
    		let funx = func()
    		funx.next(); //'用户数据'。----相当于大门钥匙
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    这篇一定要先理解前面,才能看懂最后的实例!

    其他链接

    【es6】教程

  • 相关阅读:
    MapReduce执行流程
    为什么使用Python保存的视频特别大!!(数据速率/总比特率)
    const char *转 LPCWSTR
    八股文之算法
    npm install常见报错及问题
    c# 弹出背景透明图
    MHA高可用配置及故障切换
    如何高效地从0搭建一个游戏项目
    Java 中的日期时间总结
    Hadoop生态圈中的Flume数据日志采集工具
  • 原文地址:https://blog.csdn.net/weixin_44899940/article/details/126180701