2019-07-23 17:16:20 2881浏览
关于ES6语法扣丁学堂HTML5培训小编已经给大家分享过一篇文章了,那就是《扣丁学堂HTML5培训之谈谈ES6语法(汇总上篇)》本篇文章小编接着给大家分享关于ES6语法的知识,下面就随小编一起来看一下吧。
数组扩展
数组扩展运算符
数组扩展运算符(spread)是三个点(...)。它好比rest参数的逆运算,将一个数组转为用空格分隔的参数序列。
console.log(...[1,2,3]);//123 console.log(1,...[2,3,4],5);//12345
functionfn(...values){ console.log(values);//['jia','ming'] } fn('jia','ming');
Function.prototype.call2=function(context,...args){//这里使用到rest参数 context=context||window;//因为传递过来的context有可能是null context.fn=this;//让fn的上下文为context constresult=context.fn(...args);//这里使用了数组扩展运算符 deletecontext.fn; returnresult;//因为有可能this函数会有返回值return } varjob='outterteacher'; varobj={ job:'innerteacher' }; functionshowJob(){ console.log(this.job); } showJob();//outterteacher showJob.call2(obj);//innerteacher
答案是undefined。在前一篇中也提到过,ES6语法声明的变量是不会挂载在全局对象上的~
Array.from方法用于将两类对象转为真正的数组:类似数组的对象(array-likeobject)和可遍历(iterable)的对象(对象包括ES6新增的数据结构Set和Map)。
//类数组转化成数组 letarrayLike={ '0':'a', '1':'b', '2':'c', length:3 } //ES5的写法 vararr1=[].slice.call(arrayLike);//['a','b','c'] //ES6的写法 letarr2=Array.from(arrayLike);//['a','b','c']
Array.of()方法用于将一组值,转换为数组。
letarr=Array.of(2,3,'reng'); console.log(arr);//[2,3,'reng'] console.log(arr.pop());//reng
Array.of();//[] Array.of('reng');//['reng'] Array.of(2,'reng');//[2,'reng']
copyWithin(target,start=0,end=this.length):拷贝指定数组的范围值
find(fn):用于查找第一个符合条件的数组成员,没有返回undefined
findIndex(fn):用于查找第一个符合条件的数组成员的位置,没有返回-1
entries():对键值对的遍历
keys():对键的遍历
values():对值的遍历
includes(el):返回一个布尔值,表示某个数组是否包含给定的值,与字符串的include(el)方法相似
flat(num):将嵌套的数组拉平,num是遍历的深度
[1,[2,[3]]].flat(Infinity); //[1,2,3]
letarr=[[2,8],[2],[[4,6],7,6]]; console.log([...newSet(arr.flat(Infinity))]);//[2,8,4,6,7]
对象扩展
属性名表达式
ES6允许字面量定义对象时,把表达式放在方括号内:
letlastWord='lastword'; consta={ 'firstword':'hello', [lastWord]:'world', ['end'+'symbol']:'!' }; a['firstword']//'hello' a[lastWord]//'world' a['lastword']//'world' a['endsymbol']//'!'
上面整理数组扩展内容的时候,提到了数组的扩展运算符。ES2018将这个运算符引入了对象~
letz={a:3,b:4}; letn={...z};//关键点 n//{a:3,b:4}
Object.is(arg1,arg2):比较两个值是否严格相等,与===行为基本一致
Object.assign(target,source1,...):用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target)。属于浅拷贝
Object.keys(obj):返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键名
Object.values(obj):方法返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键值。
Object.entries(obj):方法返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键值对数组。
constobj={foo:'bar',baz:42}; Object.entries(obj) //[["foo","bar"],["baz",42]]
Set和Map数据结构
Set
Set翻译出来就是集合,有元素唯一性的特点。
在数组去重的场景上很有用处:
//去除数组的重复成员 [...newSet(array)] //如 console.log([...newSet([2,2,3,2])]);//[2,3]
size:返回实例成员的总数
add(value):添加某个值,返回Set结构本身
delete(value):删除某个值,返回一个布尔值,表示删除是否成功。
has(value):返回一个布尔值,表示该值是否为Set的成员
clear():清除所有成员,没有返回值。
key():返回键名的遍历器。
values():返回键值的遍历器。
entries():返回键值对的遍历器。
forEach():使用回调函数遍历每个成员
WeakSet
WeakSet结构与Set类似,也是有不重复元素的集合。但是它和Set有两个区别:
WeakSet对象中只能存放对象引用,不能存放值,而Set对象都可以.
WeakSet中对象中存储的对象值都是被弱引用的,如果没有其他的变量或属性引用这个对象值,则这个对象值会被当成垃圾回收掉.正因为这样,WeakSet对象是无法被枚举的,没有办法拿到它包含的所有元素。
varws=newWeakSet(); varobj={}; varfoo={}; ws.add(window); ws.add(obj); ws.has(window);//true ws.has(foo);//false,对象foo并没有被添加进ws中 ws.delete(window);//从集合中删除window对象 ws.has(window);//false,window对象已经被删除了 ws.clear();//清空整个WeakSet对象
Map对象保持键值对。任何值(对象或者原始值)都可以作为一个键或一个值。
Object和Map的比较:
一个Object的键只能是字符串或者Symbols,但一个Map的键可以是任意值,包括函数、对象、基本类型。
Map中的键值是有序的,而添加到对象中的键则不是。因此,当对它进行遍历时,Map对象是按插入的顺序返回键值。
Map在涉及频繁增删键值对的场景下会有些性能优势`。
...
如果你需要“键值对”的数据结构,Map比Object更合适。
constset=newSet([//数组转换为map ['foo',1], ['bar',2] ]); constm1=newMap(set); m1.get('foo')//1 constm2=newMap([['baz',3]]); constm3=newMap(m2); m3.get('baz')//3
set(key,value):set方法设置键名key对应的键值为value,然后返回整个Map结构。如果key已经有值,则键值会被更新,否则就新生成该键。
get(key):get方法读取key对应的键值,如果找不到key,返回undefined
WeakMap
WeakMap结构与Map结构类似,也是用于生成键值对的集合。但是有两点区别:
WeakMap只接受对象作为键名(null除外),不接受其他类型的值作为键名。
WeakMap的键名所指向的对象,不计入垃圾回收机制。和WeakSet相似啦。
属性方法啥的跟Map差不多,就是没有了size和forEach,因为其是不可枚举的。
Promise对象
Promise是异步编程的一种解决方案,比传统的解决方案“回调函数和事件”更合理和更强大。
Promise对象有以下两个特点:
对象的状态不受外界影响。Promise对象代表一个异步操作,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。
一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种情况:从pending变成fulfilled(fulfilled也称resolved)和从pending变成rejected。
用法
constpromise=newPromise(function(resolve,reject){ //...somecode if(/*异步操作成功*/){ resolve(value); }else{ reject(error); } })
Promise实例生成之后,可以使用then方法分别指定resolved状态和rejected状态的回调函数。
promise.then(function(value){ //success },function(error){ //failure });
functiontimeout(ms){ returnnewPromise((resolve,reject)=>{ setTimeout(resolve,ms,'done'); }); } timeout(100).then((value)=>{ console.log(value);//100ms后输出'done' });
vartimeoutID=scope.setTimeout(function[,delay,param1,param2,...]);
那么,到这里你理解了上面的例子为什么在100ms后输出done了嘛?
简单的例子看完了,看下我们在工作中使用得比较多的请求接口的例子:
constgetJSON=function(url){ constpromise=newPromise(function(resolve,reject){ consthandler=function(){ if(this.readyState!==4){ return; } if(this.status===200){ resolve(this.response);//this.response作为参数传给then中的json }else{ reject(newError(this.statusText)); } }; constclient=newXMLHttpRequest(); client.open('GET',url); client.onreadystatechange=handler; client.responseType='json'; client.setRequestHeader('Accept','application.json'); client.send(); }); returnpromise; }; getJSON('/post.json').then(function(json){ console.log('Contents:'+json); },function(error){ console.log('errorhappen',error); });
Promise.prototype.catch方法是.then(null,rejection)或.then(undefined,rejection)的别名,用于指定发生错误时的回调函数。p.then((val)=>console.log('fulfilled:',val)) .catch((err)=>console.log('rejected',err));//promise中任何一个抛出错误,都会被最后一个catch捕获 //等同于 p.then((val)=>console.log('fulfilled:',val)) .then(null,(err)=>console.log('rejected:',err));
Promise.prototype.finally()方法(其不接受任何参数)用于指定不管Promise对象最后状态如何,都会执行的操作。该方法是ES2018引入标准的。 语法:promise .then(result=>{···}) .catch(error=>{···}) .finally(()=>{···});
构造函数方法Promise.all方法用于将多个Promise实例,包装成一个新的Promise实例。
constp=Promise.all([p1,p2,p3]);
//生成一个Promise对象的数组 constpromises=[2,3,5,7,11,13].map(function(id){ returngetJSON('/post/'+id+".json"); }); Promise.all(promises).then(function(posts){ //... }).catch(function(reason){ //... });
注意,如果作为参数的Promise实例,自己定义了catch方法,那么它一旦被rejected,并不会触发Promise.all()的catch方法。所以使用Promise.all()别手痒在每个实例promise内添加错误捕获。
一道练手题
需求:使用promise改写下面的代码,使得输出的期望结果是每隔一秒输出0,1,2,3,4,5,其中i<5条件不能变
for(vari=0;i<5;i++){ setTimeout(function(){ console.log(i); },1000) } console.log(i);
consttasks=[];//存放promise对象 for(leti=0;i<5;i++){ tasks.push(newPromise((resolve)=>{ setTimeout(()=>{ console.log(i); resolve(); },1000*i); })); } Promise.all(tasks).then(()=>{ setTimeout(()=>{ console.log(tasks.length); },1000); }); //每隔一秒输出0,1,2,3,4,5
想要了解更多关于HTML5开发方面内容的小伙伴,请关注扣丁学堂HTML5培训官网、微信等平台,扣丁学堂IT职业在线学习教育有专业的HTML5讲师为您指导,此外扣丁学堂老师精心推出的HTML5视频教程定能让你快速掌握HTML5从入门到精通开发实战技能。扣丁学堂H5技术交流群:673883249。
【关注微信公众号获取更多学习资料】 【扫码进入HTML5前端开发VIP免费公开课】