ES5_6_7
ES6_Generator函数
-
概念
- 1、ES6提供的解决异步编程的方案之一
- 2、Generator函数是一个状态机,内部封装了不同状态的数据,
- 3、用来生成遍历器对象
- 4、可暂停函数(惰性求值), yield可暂停,next方法可启动。每次返回的是yield后的表达式结果
-
特点:
-
1、function 与函数名之间有一个星号(*)
-
2、内部用yield表达式来定义不同的状态
-
例如: function* generatorExample(){ let result = yield 'hello'; // 状态值为hello yield 'generator'; // 状态值为generator }
-
3、generator函数返回的是指针对象(接11章节里iterator),而不会执行函数内部逻辑
-
4、调用next方法函数内部逻辑开始执行,遇到yield表达式停止,返回{value: yield后的表达式结果/undefined, done: false/true}
-
5、再次调用next方法会从上一次停止时的yield处开始,直到最后
-
6、yield语句返回结果通常为undefined, 当调用next方法时传参内容会作为启动时yield语句的返回值。
-
-
<script type="text/javascript"> //测试 function* generatorTest() { console.log('函数开始执行'); yield 'hello'; console.log('函数暂停后再次启动'); let result=yield 'generator'; console.log(result); } // 生成遍历器对象 let Gt = generatorTest();//返回的是指针对象 // 执行函数,遇到yield后即暂停 console.log(Gt); // 遍历器对象 let result = Gt.next(); // 函数执行,遇到yield暂停 console.log(result); // {value: "hello", done: false} result = Gt.next(); // 函数再次启动 console.log(result); // {value: 'generator', done: false} result = Gt.next('这里可以传值');//yield的语句默认返回undefined,如果不传值默认undefined console.log(result); // {value: undefined, done: true}表示函数内部状态已经遍历完毕 // 对象的symbol.iterator属性 指向遍历器对象 let obj={usernameL:'xuefeng',age:12}; obj[Symbol.iterator]=function* myTest() { yield 1, yield 2, yield 3 }; for (let i of obj) { console.log(i); }//输出 1 2 3 </script>
ES6_Generator函数应用
-
第一步先开服务器 cmd中
- F:\前端视频教程\9尚硅谷-ES5_6_7\code\ES5_6_7\code\es_server>node bin/www
-
测试服务器是否打开
-
<script type="text/javascript"> // 案例练习 /* * 需求: * 1、发送ajax请求获取新闻内容 * 2、新闻内容获取成功后再次发送请求,获取对应的新闻评论内容 * 3、新闻内容获取失败则不需要再次发送请求。 * * */ function getNews(url) { $.get(url,function (data) { console.log(data); let url= `http://localhost:3000`+data.commentsUrl; SX.next(url);//此处传入url会作为 yield getNews(url);中的url //回调函数中的next函数被调用,就说明前面一定执行成功 }) } function* sendXML() { let url=yield getNews('http://localhost:3000/news?id=3'); yield getNews(url); } //获取遍历器对象 let SX=sendXML(); SX.next();//先调用这个next方法 此时指针下移 </script>
ES6_async函数详解及应用
-
async函数(源自ES2017)
-
概念: 真正意义上去解决异步回调的问题,同步流程表达异步操作
-
本质: Generator的语法糖
-
语法:
-
async function foo(){ await 异步操作; await 异步操作; }
-
-
特点:
- 1、不需要像Generator去调用next方法,遇到await等待,当前的异步操作完成就往下执行
- 2、返回的总是Promise对象,可以用then方法进行下一步操作
- 3、async取代Generator函数的星号
*
,await取代Generator的yield - 4、语意上更为明确,使用简单,经临床验证,暂时没有任何副作用
-
<script type="text/javascript"> //async的基本使用 async function foo() { return new Promise( resolve => { // setTimeout(function () { // resolve(); // },2000) setTimeout(resolve(),2000); }) } async function test() { console.log('开始执行',new Date().toTimeString()); await foo(); console.log('执行完毕',new Date().toTimeString()); } test(); //async里await返回值 async function asyncPrint() { let result=await Promise.resolve('promise'); console.log(result); result=await Promise.reject('失败了...'); console.log(result); } asyncPrint();//报错 Uncaught (in promise) 失败了... </script>
-
<script type="text/javascript"> // 案例练习 /* * 需求: * 1、发送ajax请求获取新闻内容 * 2、新闻内容获取成功后再次发送请求,获取对应的新闻评论内容 * 3、新闻内容获取失败则不需要再次发送请求。 * * */ async function getNews(url) { return new Promise((resolve, reject) => { $.ajax({ method: 'GET', url,//同名的属性可以省略不写 success: data => resolve(data),//ES6箭头函数 /*error: function (error) {//正常写法 reject(); }*/ error: error =>resolve(false)//当出错的时候 返回false }) }) } async function sendXML() { let result=await getNews('http://localhost:3000/news?id=2') console.log(result); if(!result){alert('暂时没有评论');}//出错result为false 取反就为true result=await getNews('http://localhost:3000'+result.commentsUrl); console.log(result); } sendXML(); </script>
ES6_class类使用详解
-
通过class定义类/实现类的继承
-
在类中通过constructor定义构造方法
-
通过new来创建类的实例
-
通过extends来实现类的继承
-
通过super调用父类的构造方法
-
重写从父类中继承的一般方法
-
<script type="text/javascript"> /*function Person(name.age) { this.age=age; this.name=name; } let person=new Person('xuefeng',12);*/ //定义一个人物的类 class Person{ //类的构造方法 constructor(name,age){ this.name=name; this.age=age; } //类的一般方法 showName(){ console.log('子类实例也能调用我'); console.log(this.name,this.age); }//这些方法都定义在原型上 } let person=new Person('tianjinfeng',12); person.showName(); class StarPerson extends Person{ constructor(name,age,salary){ super(name,age);//调用父类的构造方法 一定要把父类构造器的参数传过来 this.salary=salary; } showName() {//父类的方法重写 console.log('调用子类的方法'); console.log(this.name,this.age,this.salary); } } let p1=new StarPerson('daofeng',12,12000); console.log(p1); p1.showName();//daofeng 12 12000 </script>
ES6_字符串,数组的扩展
-
includes(str) : 判断是否包含指定的字符串
-
startsWith(str) : 判断是否以指定字符串开头
-
endsWith(str) : 判断是否以指定字符串结尾
-
repeat(count) : 重复指定次数
-
<script type="text/javascript"> let str='awsl'; console.log(str.includes('a'));//true console.log(str.startsWith('a'));//true console.log(str.endsWith('l'));//true console.log(str.repeat(3));//awslawslawsl </script>
-
二进制与八进制数值表示法: 二进制用0b, 八进制用0o
-
Number.isFinite(i) : 判断是否是有限大的数
-
Number.isNaN(i) : 判断是否是NaN
-
Number.isInteger(i) : 判断是否是整数
-
Number.parseInt(str) : 将字符串转换为对应的数值
-
Math.trunc(i) : 直接去除小数部分
-
<script type="text/javascript"> console.log(0b1010);//10 console.log(0o75);//61 console.log(Number.isFinite(Infinity));//false Infinity为无限大的书 console.log(Number.isNaN(NaN));//true console.log(Number.isInteger(123.0));//true console.log(Number.parseInt('a1s5d6'));//NaN console.log(Number.parseInt('123a'));//123 console.log(Math.trunc(123.231));//123 </script>
ES6_数组方法的扩展
-
Array.from(v) : 将伪数组对象或可遍历对象转换为真数组
-
Array.of(v1, v2, v3) : 将一系列值转换成数组
-
find(function(value, index, arr){return true}) : 找出第一个满足条件返回true的元素
-
findIndex(function(value, index, arr){return true}) : 找出第一个满足条件返回true的元素下标
-
<script type="text/javascript"> let btns=document.getElementsByTagName('button');//这得到的数组就是伪数组,伪数组没有数组的一般方法 /* forEach(function (item,index) { console.log(item); });//报错 伪数组不能遍历*/ Array.from(btns).forEach(function (item,index) { console.log(item); }); let arr=Array.of(1,4,'awsl',false); console.log(arr);//(4) [1, 4, "awsl", false] let arr2=[4,5,8,1,9,3,7,6,5]; let result=arr2.find(function (item,index) { return item>5; }); console.log(result);//8 let index=arr2.findIndex(function (item,index) { return item>5; }); console.log(index);//2 </script>
ES6_对象方法的扩展
-
1.Object.is(v1, v2) :判断2个数据是否完全相等 以字符串形式判断
-
2.Object.assign(target, source1, source2…) :将源对象的属性复制到目标对象上
-
3.直接操作
__proto__
属性let obj2 = {}; obj2.__proto__ = obj1;
-
<script type="text/javascript"> console.log(0 == -0);//true console.log(NaN == NaN);//false NaN与任何值都不相等 console.log(Object.is(0,-0));//false 字符串0和字符串-0是不一样的 console.log(Object.is(NaN,NaN));//true 以字符串的形式来判断 let obj={}; let obj1={username: 'xuefeng',age:12}; let obj2={sex:'女'}; Object.assign(obj,obj1,obj2); console.log(obj);//age: 12 sex: "女" username: "xuefeng" let obj3={}; let obj4={money :12000}; obj3.__proto__=obj4; console.log(obj3);//{} console.log(obj3.money);//12000 </script>
ES6_set,map容器详解
-
1.Set容器 : 无序不可重复的多个value的集合体
- Set()
- Set(array)
- add(value)
- delete(value)
- has(value)
- clear()
- size
-
2.Map容器 : 无序的 key不重复的多个key-value的集合体
- Map()
- Map(array)
- set(key, value)//添加
- get(key)
- delete(key)
- has(key)
- clear()
- size
-
<script type="text/javascript"> let set=new Set(['a','w','s','l']); console.log(set.size,set);//4 Set(4) {"a", "w", "s", "l"} set.add(2); console.log(set.size,set);//5 Set(5) {"a", "w", "s", "l", 2} console.log(set.has('a'));//true let map=new Map([ ['daofeng',12],['xuefeng',12],['tianjinfeng',12]]); console.log(map);//Map(3) {"daofeng" => 12, "xuefeng" => 12, "tianjinfeng" => 12} map.set(10,'dian'); </script>
ES6_for of用法详解
-
for(let value of target){}循环遍历
1. 遍历数组 2. 遍历Set 3. 遍历Map 4. 遍历字符串 5. 遍历伪数组
-
<script type="text/javascript"> let arr=[1,4,7,5,4,8]; let arr1=arr; arr=[]; let set=new Set(arr1);//Set方法可以用来去重 for(let i of set){ arr.push(i);//向arr里添加元素 } console.log(arr);//Array(5) </script>
ES6_深度克隆
-
1、数据类型:
- 数据分为基本的数据类型(String, Number, boolean, Null, Undefined)和对象数据类型
- 基本数据类型:
特点: 存储的是该对象的实际数据 - 对象数据类型:
特点: 存储的是该对象在栈中引用,真实的数据存放在堆内存里
- 基本数据类型:
- 数据分为基本的数据类型(String, Number, boolean, Null, Undefined)和对象数据类型
-
2.复制数据
- 基本数据类型存放的就是实际的数据,可直接复制
- let number2 = 2;
let number1 = number2;
- let number2 = 2;
- 克隆数据:对象/数组
- 1、区别: 浅拷贝/深度拷贝
判断: 拷贝是否产生了新的数据还是拷贝的是数据的引用
知识点:对象数据存放的是对象在栈内存的引用,直接复制的是对象的引用
let obj = {username: ‘kobe’}
let obj1 = obj; // obj1 复制了obj在栈内存的引用 - 2、常用的拷贝技术
1). arr.concat(): 数组浅拷贝
2). arr.slice(): 数组浅拷贝
3). JSON.parse(JSON.stringify(arr/obj)): 数组或对象深拷贝, 但不能处理函数数据
4). 浅拷贝包含函数数据的对象/数组
5). 深拷贝包含函数数据的对象/数组
- 1、区别: 浅拷贝/深度拷贝
- 基本数据类型存放的就是实际的数据,可直接复制
-
<script type="text/javascript"> /* //不会影响原数据 let str='abcd'; let str2=str; console.log(str2);//abcd str2=''; console.log(str); let bool1=true; let bool2=bool1; bool2=false; console.log(bool1);//true //会改变原数据 let obj={username:'xuefeng',age:12}; let obj1=obj; console.log(obj1); obj1.username='daofeng'; console.log(obj.username);//daofeng //拷贝数组/对象 没有生成新的数据而是复制了一份引用 let arr=[1,4,{username:'jifeng',age:12}]; let arr2=arr; arr2[0]='awsl'; console.log(arr,arr2);//Array(3) [ "awsl", 4, {…} ] Array(3) [ "awsl", 4, {…} ] */ /* 拷贝数据: 基本数据类型 拷贝后生成一份新的数据,修改拷贝以后的数据不会影响原数据 对象/数组 拷贝后不会生成新的数据,而拷贝是引用, 修改拷贝后的数据会影响原来的数据 拷贝数据的方法 1.直接赋值给一个变量 //浅拷贝 2.Object.assign() //浅拷贝 3.Array.prototype.concat() //浅拷贝 4.Array.prototype.slice() //浅拷贝 5.JSON.parse(JSON.stringify()) //深拷贝(深度拷贝),拷的数据里不能有函数 浅拷贝(对象/数组): 特点: 拷贝的引用,修改拷贝以后的数据也会影响原数据 深拷贝(对象/数组): 特点:拷贝的时候生成新数据,修改拷贝以后的数据不会影响原数据 */ let newObj={username:'dian'}; let newObj2=Object.assign(newObj); console.log(newObj2);//{username: "dian"} newObj.username='feng'; console.log(newObj);//{username: "feng"} console.log(newObj2);//{username: "feng"} let arr=[1,3,{username:'xiang'}]; let arr2=arr.concat();//修改arr2的数据影响了原数据 所以是浅拷贝 console.log(arr2);//Array(3) [ 1, 3, { username: "lei"} ] arr2[2].username='lei'; console.log(arr);//Array(3) [ 1, 3, { username: "lei"} ] let arr3=arr.slice();//两个参数startIndex endIndex 修改了arr3的数据也影响了原数据 所以是浅拷贝 arr3[2].username='shijinfeng'; console.log(arr);//Array(3) [ 1, 3, { username: "shijinfeng"} ] console.log('*********'); let arr4=JSON.parse(JSON.stringify(arr));//arr4改变没有修改原数据 所以是深拷贝 console.log(arr4);//Array(3) [ 1, 3, { username: "yingfeng"} ] arr4[2].username='yingfeng'; console.log(arr);//Array(3) [ 1, 3, { username: "shijinfeng"} ] </script>
-
深度克隆的方法(此方法还有误,需要调试)
-
<script type="text/javascript"> /** * 如何实现深度拷贝(克隆) * 拷贝的数据里有对象/数组 * 拷贝的数据里不能有对象/数组, * 即使有对象/数组可以继续遍历对象、数组拿到里面每一项值,一直拿到是基本数据类型,然后再去复制,就是深度拷贝 */ //知识储备 /* 如何判断数据类型 arr ---> Array null==>Null 1.typeof返回的数据类型:String Number Boolean Undefined Object Function 2.Object.prototype.toString.call(obj) 3. */ let result='abcd'; console.log(Object.prototype.toString.call(result));//[object String] console.log(Object.prototype.toString.call(result).slice(8,-1));//String //for in循环 对象(的属性名) 数组(的下标) let obj={username:'xuefeng',age:12}; for (let i in obj){ console.log(i); } let arr =[1,3,'awsl']; for (let i in arr){ console.log(i); } //定义检测数据类型的功能函数 function checkedType(target) { return Object.prototype.toString.call(target); } //实现深度克隆 --> 对象/数组 function clone(target) { //判断拷贝的数据类型 //初始化变量result 成为最终克隆的数据 let result,targetType =checkedType(target); if(targetType === 'Object'){ result ={}; }else if(targetType === 'Array'){ result=[]; }else{ return target;// 如果是其他数据类型不复制,直接将数据返回 } //遍历目标数据 for(let i in target){ //获取遍历数据结构的每一项值 let value=target[i]; //判断目标结构里的每一项值是否存在对象/数组 if(checkedType(value) === 'Object'||checkedType(value) ==='Array'){ //继续遍历获取到的value值 result[i]=clone(value); }else{//获取到的value值是基本的数据类型或者是函数 result[i]=value; } } return result; } let arr3=[1,2,{username:'xuefeng',age:12}]; let arr4=clone(arr3); console.log(arr4);//Array(3) [ 1, 2, { username: "xuefeng", age: 12} ] arr4[2].username='lian'; console.log(arr3,arr4); let obj3={username:'tianjinfeng',age:12}; let obj4=clone(obj3); console.log(obj4);//{username: "tianjinfeng", age: 12} obj4.username='shijinfeng'; console.log(obj3,obj4); </script>
-
ES7_方法介绍
-
1.指数运算符(幂):
**
-
2.Array.prototype.includes(value) : 判断数组中是否包含指定value
-
<script type="text/javascript"> console.log(3 ** 3);//27 let arr=[1,4,7,59,11,'abv']; console.log(arr.includes('a'));//false 这里判断是否对等 不是模糊匹配 </script>