try…catch
try...catch用来检测代码执行过程中出现的错误,并捕获错误(可以避免由于某个js错误造成页面渲染出错)- 实用程度:
1 | try{ |
1 | try { |
async/await
async/await是ES8写入的JS标准我们使用
async来定义一个异步函数,使用await等待一个异步的执行结果(准确说await等待一个Promise对象。await必须在async function内部使用),async隐式的返回一个Promise;(官方描述:async function用来定义一个返回AsyncFunction对象的异步函数。异步函数是指通过事件循环异步执行的函数,它会通过一个隐式的Promise返回其结果。如果你在代码中使用了异步函数,就会发现它的语法和结构会更像是标准的同步函数。)实用程度:
重要程度:
async/await可以让我们以更加优雅的姿势来写异步函数,或者说采用async/await之后,我们就不需要再去考虑这个函数是不是异步的。在此之前,对于异步函数,我们必须等待异步函数执行完成之后,拿到异步函数的结果,才可以继续往下进行,基于此必须写深深的回调,在回调里拿结果,在回调里继续写异步…….俗称“回调地狱”。ES6的出现,带来了新的异步解决方案Promise, 但Promise真的是完美的吗?虽然我们确实走出了“回调地狱”,但相对的不过是把回调变成了纵向的,形成了一个纵向的回调链。异步编程的最高境界,就是应该让我们不用再去关心它是不是异步。async/await的出现,就是让我们以同步的方式来编写异步代码。async/await依赖于Promise,是Generator函数的语法糖。async/await不会替换Promise,但是好像可以替换Generator,所以,Generator就不讲了(我自己也不怎么用)
1 | // 使用 async 定义一个异步函数 |
1 | // 本来不想用延时器的,但实在没想到更适合的例子 |
如上代码,我们本意是想fn() 执行结束之后拿到返回值,将返回值给变量time 然后打印出time,但由于fn()内的setTimeout是异步执行的,并不会等待 5秒等fn执行完成之后再打印time,所以造成的结果就是先打印time = undefined,等了5秒后fn才执行完。
但是这是我们理想的代码写法,虽然目前它没有按我们的理想执行,但使用async/await 之后,我们就可以使我们理想的代码按照我们的理想去执行。
结合Promise去写理想代码
1 | const fn = () => { |
最佳实践应该是
try...catch+async/await+Promise,三者结合写段代码
1 | const createPromise = () => { |
扩展运算符
即... ,用来将数组或者对象进行展开,也可以展开字符串,还可以在函数调用时对入参进行展开(描述不准确,看代码演示);(官方描述: 展开语法(Spread syntax), 可以在函数调用/数组构造时, 将数组表达式或者string在语法层面展开;还可以在构造字面量对象时, 将对象表达式按key-value的方式展开。)
- 常用来用来实现数组和对象的深拷贝
1 | /************************** 浅拷贝 ****************************/ |
我们本意是希望将numList1拷贝一份给numList2,然后对numList2进行修改,numList1我们可能在其他地方还需要用,但由于js对引用类型实行的时浅拷贝,所以会造成numList1也被改变,基于此,我们希望numList2改变不会影响numList1,我们就需要对numList1进行深拷贝
1 | /************************** map深拷贝 ****************************/ |
- 对象深拷贝
1 | const obj1 = {name: '李白'}; |
对于以上写法,如果
obj2中的属性在obj1中已经存在了,则obj2中的属性会覆盖obj1中的属性;后覆盖前以上写法也是刻意为之,对象深拷贝还有其他API
- 字符串扩展运算符和在函数调用时
1 | console.log(...'qasxxxxxdrrrrrrrfgbbbhuuuujmmmmko'); |