06-ES6+学习手册

ES6+学习手册

ES全称ECMAScript,是一种脚本语言的标准化规范,要知道,早期的JS是没有一个规范的,而ES的诞生则奠定了JS的基本规范,2015年正式发布第6版,是十年以来最大的一次更新,相比于ES5增加了许多新的特性,比如let/const,promise等等。下面就来学一下ES6的一些重要而常用新特性吧!

一、let和const

我们知道,es5定义变量和常量都是用var的,而es6则新增了两个关键字letconst,主要区别如下:

varletconst
存在变量提升不存在变量提升不存在变量提升
只有全局作用域和函数作用域有块级作用域有块级作用域
可以声明同名变量不能声明同名变量不能声明同名变量
可以先声明不赋值可以先声明不赋值一旦声明必须赋值,同时不能改变

二、ES6解构赋值

解构赋值是对赋值运算符的扩展,方便了复杂对象中数据字段的获取。

2.1数组的解构

es6可以将一个数组自动匹配到另一个数组变量

    <script>
        let [a,b,c]=[1,2,3]
        console.log(a) //打印1
        console.log(b) //打印2
        console.log(c) //打印3
    </script>

而且也可以嵌套匹配

   <script>
        let [a, [[b], c]] = [1, [[2], 3]];
        console.log(a)
        console.log(b)
        console.log(c)
    </script>

甚至可以对字符串解构

	<script>
        let [a, b, c, d, e] = 'hello';
        console.log(a)
        console.log(b)
        console.log(c)
        console.log(d)
        console.log(e)
    </script>

2.2对象的解构

除了解构数组,还可以解构对象

	<script>
        let {mb1,mb2}={mb1:'aaa',mb2:'bbb'}
        console.log(mb1)
        console.log(mb2)
    </script>

当然也是可以嵌套的,这里就不展示了,大概和数组的差不多。

三、ES6字符串

3.1子串识别

ES6之前我们判断字符串是否包含子串,用的是indexOf方法,ES6新增了子串的识别方法

  • includes():判断是否找到参数字符串,返回一个布尔值

  • startswith():判断参数字符串是否在原字符串尾部,返回布尔值

  • startswith():判断参数字符串是否在原字符串尾部,返回布尔值

    let string = "apple,banana,orange";
    string.includes("banana");     // true
    string.startsWith("apple");    // true
    string.endsWith("apple");      // false
    string.startsWith("banana",6)  // true
    

3.2字符串重复

  • repeat():字符串重复指定次数返回,返回新的字符串

    console.log("Hello,".repeat(2));  // "Hello,Hello,"
    

3.3字符串补全

  • padStart:表示用参数字符串从头部补全原字符串,返回新的字符串。
  • padEnd:表示用参数字符串从尾部补全原字符串,返回新的字符串。
console.log("h".padStart(5,"o"));  // "ooooh"
console.log("h".padEnd(5,"o"));    // "hoooo"

四、ES6箭头函数

ES6提供了一种更加简洁的函数书写方式,那就是箭头函数,我们之前写函数的方法是这样的:

const test = function(num){
	return num*2
}

而箭头函数的写法是:

const test = ()=>{
	return num*2
}

如果函数只有一个参数,则可以省略小括号:

const test = num =>{
	return num*2
}

而如果只有一条执行语句,甚至可以省略后面的大括号,甚至可以不写return:

const test = num => num*2

当然,箭头函数与普通函数的区别远不止如此,他带给我们最大的改变就是this的指向。在ES6之前,JS的this对象一直是一个令人头大的问题,在回调函数中,经常会看到var that = this这样的代码,这是为了将外部的this传递到回调函数中。而箭头函数的出现解决了这个问题。

箭头函数不会创建自己的this,他只会从自己的作用域链上找父级执行上下文的this。简单来说,不是谁调用这个函数,它的this就是谁,而是取决于上层执行上下文的this。举个栗子:

<script>
			var id = 0
			var obj = {
				id: 1,
				show1: function () {
					setTimeout(() => {
						console.log(this.id)
					}, 1000)
				},

				show2: function () {
					setTimeout(function () {
						console.log(this.id)
					}, 2000)
				},
			}

			obj.show1() // 打印 1
			obj.show2() // 打印 0
		</script>

obj分别调用了show1和show2两个方法,因此它们的this都是指向obj的。而show1中setTimeout是箭头函数,从作用域链找中找到show1中的this,因此它的this就是obj对象;而show2中setTimeout是普通函数,函数自主调用,所以他的this就是window对象。

五、ES6模块

在ES6之前,实现模块化使用的是RequireJS,比如你能看到如下的写法:

var express = require('express')

而ES6引入了模块化,一个文件可以默认为一个模块,其设计思想是在编译时就能确定模块化的依赖,以及输入输出的变量,分为导出模块和导入模块。

5.1export

export命令用于规定模块的对外接口,它有以下几种书写方式:

  • 变量

    //demo1.js
    let name = 'JJY'
    let age = 22
    export{name,age}
    
  • 函数

    //单个导出
    export function test(){
      console.log('输出test')
    }
    
    function test2(){
      return 'hello2'
    }
    function test3(){
      return 'hello3'
    }
    //多个导出,并用as用别名
    export {
      test2 as t2,
      test3 as t3,
    }
    
  • 还有一种写法,export default是将变量赋值给defalut,一个文件只能输出一个,系统允许引用的时候给他取任意名字:

    //demo3.js
    export default {
    	name:'JJY',
    	age:22
    }
    //或者
    export default function test(){
    	console.log('test')
    }
    

5.2import

import是导入模块的指令,针对export普通的写法,import的写法如下:

import {name,age} from './demo1.js'
import {t1} from './demo2.js'

也可以用as重新定义导出接口的名称,隐藏内部的变量

import{name as test} from './demo1.js'

对于export defalut导入时必须指定一个名称,比如我要引入上面demo3

import d3 from './demo3.js'  //注意不用{}

六、Promise

首先我们要知道为什么会出现promise。

在程序开发的过程中不可避免会产生异步操作,所谓异步操作是程序在执行该操作时,用户可以不必等待其完成进而进行下一步操作,而等异步操作完成后,再返回其对应的结果。网络请求就是典型的异步操作。当程序向指定的URL发起请求后返回对应诗句,处理异步通过回调函数来实现的。在ES6之前ajax处理回调都是调用successfail,但这会引发一个问题,回调地狱。

在这里插入图片描述

简单来说就是在一个网络请求的success中又嵌套了网络请求,一旦需要进行多次的网络请求,则会形成多层回调,当回调函数中需要进行许多行代码的操作时,每一层回调的间隔会变得很大,从而导致代码可读性差,维护性差等问题,因此就出现了Promise:

在这里插入图片描述

Promise是异步编程的一种解决方案,它的链式编程可以使得程序更加扁平化,把执行代码和处理结果的代码清晰地进行了分离。因为promise是一个对象,可以获取异步操作的消息,所以下面就先来简单介绍一下promise的三种状态。

  • pending–等待状态
  • fulfilled–满足状态(成功)
  • rejected–拒绝状态(失败)

Promise从未完成的状态开始,如果成功他会成为满足状态,并且将成功的结果传给它,然后调用resolve()方法保存,再通过.then()进行处理,同理若失败,则进入拒绝状态,调用reject()方法,再通过.catch()处理。

说了这么多,可能你对Promise还是一头雾水,那我们就举一个栗子吧,用setTimeout来模拟网络请求

let request = (time) => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            let random = Math.random()
            if (random >= 0.1) {
                resolve(time)
            } else {
                throw new Error('出错了')
            }
        }, time)
    })
}

request(200).then((response) => {         
    console.log('第一次请求成功了', response)
    return request(response + 200)
}).then((result) => {
    console.log('第二次请求成功了', result)
    return request(result + 200)
}).then(result => {
    console.log('第三次请求成功了', result) 
})

可以看到,我们模拟了三层网络请求,但实际上写出来的代码没有层层嵌套的感觉,看上去就像在做同步操作一样,这就是我们所谓的解决了回调地狱的好处。

七、async和await

这两个东西是es7才出来的(知道标题为什么叫es6+了吧~),它们也是与异步操作有关的关键字,实际上也是对Promise的进一步封装。为什么这么说呢?这里莱卡看看它俩的使用规则。

  • async 表示这是一个async函数, await只能用在async函数里面,不能单独使用。
  • async返回的是一个Promise对象(嗯?),await就是等待这个promise的返回结果后,再继续执行。
  • await 等待的是一个Promise对象,后面必须跟一个Promise对象,但是不必写then(),直接就可以得到返回值。

在上面Promise的例子中,虽然我们解决了回调地狱,但可能有人觉得.then太多,看上去也是比较麻烦,那么我们就可以用async/await来进一步优化。

let request = (time) => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            let random = Math.random()
            if (random >= 0.1) {
                resolve(time)
            } else {
                throw new Error('出错了')
            }
        }, time)
    })
}

async function test() {
    let result01 = await request(200)
    let result02 = await request(result01 + 200)
    let result03 = await request(result02 + 200)
    console.log(result03)
}

test()

可以看见,我们用async定义了test方法,在其内部又用await来执行异步操作,这样一来代码看上去就更加简洁,可读性也增强了很多。当然因为async返回的还是一个promise,因此我们还能继续对它扩展,用.then来接收。

async function test() {
    let result01 = await request(200)
    let result02 = await request(result01 + 200)
    let result03 = await request(result02 + 200)
    return result03
}

test().then(result => {
  console.log(result)
})

总结

这次的学习指南到此结束,上面罗列出来的都是ES6的一些十分重要而且常用的特性,当然ES6、ES7甚至ES8等等的新特性远不止这些,不过有些不常用,而且我也还没完全弄懂,因此也就没有收录在这篇指南当中,有兴趣的小伙伴可以自行去了解,我也会自己继续学习的,谢谢~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值