ECMAScript 6
模块化语法
第一种语法
导出 export
语法:export default {xxx}
作用:导出一个任意类型的变量
在一个模块中,export default
只能导出一次;
导入 import
语法:import xxx from '...'
作用:导入另外一个模块 export default
导出的变量;可以自定义变量名接收;
1 | // a.js 导出一个任意类型的变量,只能使用导出一次,不然会报错 |
第二种语法
导出 export
语法:export const {xxx}
作用:导出一个声明后的任意类型的变量
在一个模块中,export
可以导出多次,也可以用一次性导出多个变量;
导入 import
语法:import {} from '...'
作用:导入另外一个模块 export
导出的变量;一次性接收,但是变量名必须与导出的模块中的变量名相同;
1 | // a.js 导出一个或者多个变量 |
1 | // 一次性导出: |
ES6 变量与声明
变量声明的两种方式
const
:声明一个常量,不能修改赋值,复杂类型不能修改引用地址,但是可以修改属性;
let
:声明一个变量,可以修改值和应用地址;
const
和 let
特点:
- 声明的是局部常量/变量;
- 在同一作用域不能重复声明,作用向下兼容;
- 不会被预解析,只能先声明后使用;
- 支持局部作用域(代码块);
ES6块级作用域
每一对{}内都是局部作用域;也叫代码块;
所以可以使用let来完成for循环闭包函数的功能;
1 | for (let i = 0; i < 10; i++){ |
字符串
字符串模板
对于一个字符串HTML结构来说,用引号包裹后,不支持换行,如果换行则需要拼接;
ES6 新的字符串语法:字符串模板;支持字符串内换行;
反引号(键盘ESC下面的键)包裹
字符串模板可以写JavaScript表达式
1 | `字符串${}字符串` |
字符串 String
新增字符串方法
startsWith("data");
-判断字符串是否以data参数开头,返回布尔类型;
1 | "abcdefg".startsWith("abc");//true |
endsWith("data");
-判断字符串是否以data参数结尾,返回布尔类型;
1 | "abcdefg".endsWith("fg");//true |
ES6 对象 Object
对象添加属性简写
ES6中对象属性的简化语法,属性名相同的时候可以简写;
1 | this.list.push({ id: id, name: name, content: content }) |
对象简化语法
- 对象中的属性和方法,都可以使用简化语法
1 | /* 属性的简化语法: */ |
对象扩展运算符
- 注意:该语法不是真正的ES规范,需要使用
stage-2
解析
1 | var obj = { name: 'jack', age: 19 } |
属性名表达式
- ES6 允许字面量定义对象时,用表达式作为对象的属性名,即把表达式放在方括号内。
1 | var propKey = 'foo' |
ES6 数组 Array
ES6 数组新增方法
[].find
遍历数组,参数是一个回调函数,回调函数如果return了一个真值,则会返回第一个满足这个条件的元素;
findIndex(() => {})
遍历数组,参数是一个回调函数,回调函数如果return了一个真值,则会返回当前这个元素的下标;
数组扩展运算符
- 扩展运算符(spread)是三个点(…)。作用:将一个数组转为用逗号分隔的参数序列
1 | var arr = ['a', 'b', 'c'] |
ES6 函数
方法函数
对象内函数封装的新方法;this指向和原来一样;
1 | { |
箭头函数
- ES6箭头函数
- 注意 1:函数体内的this对象,就是定义时所在的对象(一般是外层函数中的this)
- 注意 2:无法使用arguments,没有arguments对象
- 注意 3:不能当作构造函数,不能使用new创建对象
- 注意:不要在Vue的选项属性或回调上使用箭头函数
- 比如:
created: () => console.log(this.a)
或vm.$watch('a', newValue => this.myMethod())
- 比如:
- 箭头函数
=>
goes to - 箭头函数自身没有this,会向函数外部寻找this,外部的this指向谁,箭头函数的this就指向谁;
语法:
1 | function fn() {} |
rest参数
- ES6 引入 rest 参数(形式为…变量名),用于获取函数的多余参数,这样就不需要使用arguments对象了
- 说明:rest 参数的类型是:数组
- 注意:rest 参数之后不能再有其他参数(即只能是最后一个参数),否则会报错
1 | function add(...values) { |
解构赋值
- ES6解构
- ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring)。
1 | // 对象解构 |
Promise 异步编程
- Promise 是
异步编程
的一种解决方案,它允许你以一种同步的方式编写异步代码 promise
:承诺、保证- ES6 - Promise
回调地狱
JavaScript 是单线程的,异步操作执行后不会马上的到结果,而是会执行后面的代码,所以需要在异步操作之后得到结果,在对这个结果处理,就需要使用回调函数来处理这些数据,如果异步操作一层一层嵌套,会产生回调函数嵌套回调函数,这就是回调地狱。
例如需要按顺序读取文件,由于异步操作不能结果返回的顺序;所以需要嵌套回调函数来保证顺序;
1 | // 按序读取文件:a -> b -> c -> d |
Promise 的用法
Promise 方式:将异步操作以同步操作的方式表达出来,避免了层层嵌套的回调函数
- Promise 是一个构造函数;
- 把 Promise 看成是一个容器,内部封装了异步操作;
- Promise 的参数是一个回调函数;这个回调函数有两个参数,两个回调函数;
- resolve 表示异步操作成功调用的函数
- reject 表示异步操作失败调用的函数
- 也就是说:如果异步操作成功,应该调用 resolve;如果异步操作失败,应该调用 reject
1 | const p = new Promise(function (resolve, reject) { |
Promise 的三种状态
Promise 有三种状态,Promise 内部执行的结果将决定由 pending
变为 fulfilled(已成功)
或者 rejected(已失败)
状态,这个结果是唯一的,并且不会再改变;
- Promise 对象代表一个异步操作,有三种状态:pending(初始状态/进行中/未决定的)、fulfilled(已成功)、rejected(已失败)
- 状态改变1:pending => fulfilled 表示成功的状态,调用 resolve 回调函数;
- 状态改变2:pending => rejected 表示失败的状态,调用 reject 回调函数;
- 状态确定之后,就不会再改变;
then 和 catch
实例通过调用这两方法,可以来获得 Promise 执行异步操作得到结果后的回调函数;
- 说明:获取异步操作的结果
then()
:用于获取异步操作成功时的结果 -> resolvecatch()
:用于获取异步操作失败时的结果 -> reject- 说明:
then()
方法可以有多个,按照先后顺序执行,通过回调函数返回值传递数据给下一个then()
可以通过 return
Promise 的实例对象来继续调用下一个 then()
来完成异步编程
1 | const p = new Promise((resolve, reject) => { |
Promise 解决回调地狱的问题
1 | // 通过Promise 来实现读文件的操作: |
all 和 race
Promise 的两个方法,Promise.all()
和 Promise.race()
Promise.all()
用来处理多个异步请求都完成后,在执行下一步操作;promise.all( 参数是一个['promise对象'])
每一个数组的属性都是一个promise对象;Promise.race()
用来处理多个异步请求,只要有一个先完成,就执行下一步操作;
1 | // 需求:等到多个请求都完成后,再执行某个操作 |
async 和 await
- 异步编程终极方案
- 注意:
await
只能在async
函数中使用 - 注意:
await
后面是一个Promise
实例对象 - 注意:
await
关键字用来暂停
后面的函数,等到获取到结果后,下面的代码才会执行- 这样,就可以按照代码书写的顺序来理解代码执行顺序
- 注意:
async
函数外的代码不受影响,继续按照同步方式执行 - 使用ES2017的Async功能
- async/await替代Promise的6个理由
1 | // 通过Promise 来实现读文件的操作: |
Promise 执行顺序问题
1 | let promise = new Promise(function(resolve, reject) { |
class关键字
- ES6以前,JS是没有class概念的,而是通过构造函数+原型的方式来实现的
- 注意:ES6中的class仅仅是一个语法糖,并不是真正的类,与Java等服务端语言中的类是有区别的
- ES6 - 文档
1 | class Person { |
- 类继承:
- 1 如果子类提供了 constructor,那么,必须要调用
super()
- 2 子类添加属性,必须在 super() 调用后面
- 1 如果子类提供了 constructor,那么,必须要调用
1 | // 类继承: |
静态属性和实例属性
- 静态属性:直接通过类名访问
- 实例属性:通过实例对象访问