ES6的简介
ECMAScript 6(以下简称ES6)是JavaScript语言的下一代标准。因为当前版本的ES6是在2015年发布的,所以又称ECMAScript 2015
Babel转码器
Babel 是一个广泛使用的 ES6 转码器,可以将 ES6 代码转为 ES5 代码
let和const命令
let命令
基本用法
ES6 新增了let命令,用来声明变量。它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效
|
|
使用let,声明的变量仅在块级作用域内有效,解决如下代码问题
|
|
let命令改变了语法行为,它所声明的变量一定要在声明后使用,否则报错
|
|
let不允许在相同作用域内,重复声明同一个变量
|
|
const 命令
const声明一个只读的常量。一旦声明,常量的值就不能改变
|
|
const的作用域与let命令相同:只在声明所在的块级作用域内有效
|
|
变量的解构赋值
数组的解构赋值
ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构
|
|
下面是一些使用嵌套数组进行解构的例子
|
|
解构赋值允许指定默认值
|
|
对象的解构赋值
解构不仅可以用于数组,还可以用于对象
|
|
对象的属性没有次序,变量必须与属性同名,才能取到正确的值
|
|
如果变量名与属性名不一致,必须写成下面这样
|
|
字符串的解构赋值
字符串被转换成了一个类似数组的对象
|
|
数组的对象都有一个length属性,因此还可以对这个属性解构赋值
|
|
数值和布尔值的解构赋值
解构赋值时,如果等号右边是数值和布尔值,则会先转为对象
|
|
解构赋值的规则是,只要等号右边的值不是对象或数组,就先将其转为对象.由于undefined和null无法转为对象,所以对它们进行解构赋值,都会报错
|
|
函数参数的解构赋值
函数add的参数表面上是一个数组,但在传入参数的那一刻,数组参数就被解构成变量x和y
|
|
函数参数的解构也可以使用默认值
|
|
圆括号问题
ES6 的规则是,只要有可能导致解构的歧义,就不得使用圆括号
解构赋值用途
交换变量的值
交换变量x和y的值,这样的写法不仅简洁,而且易读,语义非常清晰
|
|
从函数返回多个值
函数只能返回一个值,如果要返回多个值,只能将它们放在数组或对象里返回。有了解构赋值,取出这些值就非常方便
|
|
函数参数的定义
解构赋值可以方便地将一组参数与变量名对应起来
|
|
提取 JSON 数据
快速提取 JSON 数据的值
|
|
函数参数的默认值
指定参数的默认值,就避免了在函数体内部再写var foo = config.foo || ‘default foo’;这样的语句
|
|
遍历Map结构
任何部署了 Iterator 接口的对象,都可以用for…of循环遍历。Map 结构原生支持 Iterator 接口,配合变量的解构赋值,获取键名和键值就非常方便
|
|
如果只想获取键名,或者只想获取键值,可以写成下面这样
|
|
输入模块的指定方法
加载模块时,往往需要指定输入哪些方法。解构赋值使得输入语句非常清晰
|
|
字符串的扩展
includes, startsWith, endsWith
includes():返回布尔值,表示是否找到了参数字符串
startsWith():返回布尔值,表示参数字符串是否在原字符串的头部
endsWith():返回布尔值,表示参数字符串是否在原字符串的尾部
|
|
repeat
repeat方法返回一个新字符串,表示将原字符串重复n次
|
|
padStart,padEnd
padStart()用于头部补全,padEnd()用于尾部补全
|
|
matchAll
matchAll方法返回一个正则表达式在当前字符串的所有匹配
模板字符串
传统的 JavaScript 语言,输出模板
|
|
ES6 引入了模板字符串
|
|
模板字符串用反引号(`)标识,可以用来定义多行字符串,或者在字符串中嵌入变量
|
|
正则的扩展
略
数值的扩展
Number.isFinite, Number.isNaN
Number.isFinite()用来检查一个数值是否为有限的(finite),即不是Infinity
|
|
Number.isNaN()用来检查一个值是否为NaN
|
|
Number.isInteger()
Number.isInteger()用来判断一个数值是否为整数
|
|
函数的扩展
函数参数的默认值
ES6 之前,不能直接为函数的参数指定默认值,只能采用变通的方法
|
|
ES6 允许为函数的参数设置默认值,即直接写在参数定义的后面
|
|
参数默认值可以与解构赋值的默认值,结合起来使用
|
|
rest参数
ES6 引入 rest 参数(形式为…变量名),用于获取函数的多余参数
|
|
name属性
函数的name属性,返回该函数的函数名
|
|
箭头函数
ES6 允许使用“箭头”(=>)定义函数
|
|
如果箭头函数不需要参数或需要多个参数,就使用一个圆括号代表参数部分
|
|
如果箭头函数的代码块部分多于一条语句,就要使用大括号将它们括起来,并且使用return语句返回
|
|
箭头函数的一个用处是简化回调函数
|
|
rest 参数与箭头函数结合的例子
|
|
箭头函数有几个使用注意点
- 函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。
- 不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误。
- 不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替。
- 不可以使用yield命令,因此箭头函数不能用作 Generator 函数
|
|
箭头函数可以让setTimeout里面的this,绑定定义时所在的作用域,而不是指向运行时所在的作用域
|
|
数组的扩展
扩展运算符
扩展运算符(spread)是三个点(…)。它好比 rest 参数的逆运算,将一个数组转为用逗号分隔的参数序列
|
|
Array.from()
Array.from方法用于将两类对象转为真正的数组:类似数组的对象和可遍历的对象
|
|
Array.of()
Array.of方法用于将一组值,转换为数组
|
|
copyWithin()
在当前数组内部,将指定位置的成员复制到其他位置(会覆盖原有成员),然后返回当前数组
接受三个参数
- target(必需):从该位置开始替换数据。如果为负值,表示倒数
- start(可选):从该位置开始读取数据,默认为 0。如果为负值,表示倒数
- end(可选):到该位置前停止读取数据,默认等于数组长度。如果为负值,表示倒数
|
|
find() 和 findIndex()
find方法,用于找出第一个符合条件的数组成员,如果没有符合条件的成员,则返回undefined
|
|
findIndex方法的用法与find方法非常类似,返回第一个符合条件的数组成员的位置,如果所有成员都不符合条件,则返回-1
|
|
fill()
fill方法使用给定值,填充一个数组
|
|
fill方法还可以接受第二个和第三个参数,用于指定填充的起始位置和结束位置
|
|
entries(),keys() 和 values()
entries(),keys()和values()——用于遍历数组,可以用for…of循环进行遍历
keys()是对键名的遍历、values()是对键值的遍历,entries()是对键值对的遍历
|
|
includes()
Array.prototype.includes方法返回一个布尔值,表示某个数组是否包含给定的值
|
|
对象的扩展
属性的简介表示法
ES6 允许直接写入变量和函数,作为对象的属性和方法
|
|
ES6 允许在对象之中,直接写变量。这时,属性名为变量名, 属性值为变量的值
|
|
属性名表达式
ES6 允许字面量定义对象时,把表达式放在方括号内,作为对象的属性名
|
|
表达式还可以用于定义方法名
|
|
方法的 name 属性
对象方法也是函数,因此也有name属性
|
|
Object.is()
Object.is就是比较两个值是否严格相等,与严格比较运算符(===)的行为基本一致
|
|
Object.assign()
Object.assign方法用于对象的合并,将源对象的所有可枚举属性,复制到目标对象
|
|
如果目标对象与源对象有同名属性,或多个源对象有同名属性,则后面的属性会覆盖前面的属性
|
|
Object.assign方法实行的是浅拷贝,而不是深拷贝,即源对象跟着目标对象的属性变化而变化
|
|
对于这种嵌套的对象,一旦遇到同名属性,Object.assign的处理方法是替换
|
|
Object.assign可以用来处理数组,但是会把数组视为对象
|
|
Object.assign只能进行值的复制,如果要复制的值是一个取值函数,那么将求值后再复制
|
|
Object.keys()
ES5 引入了Object.keys方法,返回一个数组,成员是参数对象自身的所有可遍历属性的键名
|
|
Object.values()
Object.values方法返回一个数组,成员是参数对象自身的所有可遍历属性的键值
|
|
Object.entries()
Object.entries方法返回一个数组,成员是参数对象自身的所有可遍历属性的键值对数组
|
|
作用
ES6 引入了跟Object.keys配套的Object.values和Object.entries,作为遍历一个对象的补充手段,供for…of循环使用
|
|
Symbol
概述
ES6 引入了一种新的原始数据类型Symbol,表示独一无二的值
|
|
Symbol函数可以接受一个字符串作为参数,表示对 Symbol 实例的描述
|
|
Symbol 的参数是一个对象,就会调用该对象的toString方法,将其转为字符串,然后才生成一个 Symbol 值
|
|
Symbol函数的参数只是表示对当前 Symbol 值的描述,因此相同参数的Symbol函数的返回值是不相等的
|
|
作为属性名的 Symbol
Symbol 值都是不相等的,Symbol 值可以作为标识符,用于对象的属性名,就能保证不会出现同名的属性
|
|
Promise 对象
基本用法
Promise对象是一个构造函数,用来生成Promise实例
|
|
Promise实例生成以后,可以用then方法分别指定resolved状态和rejected状态的回调函数
|
|
setTimeout的例子
|
|
异步加载图片的例子
|
|
ajax操作的例子
|
|
resolve函数的参数除了正常的值以外,还可能是另一个 Promise 实例
|
|
Promise.prototype.then()
then方法的第一个参数是resolved状态的回调函数,第二个参数(可选)是rejected状态的回调函数
then方法返回的是一个新的Promise实例
采用链式写法,即then方法后面再调用另一个then方法
|
|
Module 的语法
概述
历史上,JavaScript 一直没有模块(module)体系,无法将一个大程序拆分成互相依赖的小文件
在 ES6 之前,社区制定了一些模块加载方案,最主要的有 CommonJS 和 AMD 两种。前者用于服务器,后者用于浏览器
ES6 在语言标准的层面上,实现了模块功能,而且实现得相当简单,完全可以取代 CommonJS 和 AMD 规范,成为浏览器和服务器通用的模块解决方案
|
|
严格模式
ES6 的模块自动采用严格模式,不管你有没有在模块头部加上”use strict”
严格模式主要有以下限制
- 变量必须声明后再使用
- 函数的参数不能有同名属性,否则报错
- 不能使用with语句
- 不能对只读属性赋值,否则报错
- 不能使用前缀 0 表示八进制数,否则报错
- 不能删除不可删除的属性,否则报错
- 不能删除变量delete prop,会报错,只能删除属性delete global[prop]
- eval不会在它的外层作用域引入变量
- eval和arguments不能被重新赋值
- arguments不会自动反映函数参数的变化
- 不能使用arguments.callee
- 不能使用arguments.caller
- 禁止this指向全局对象
- 不能使用fn.caller和fn.arguments获取函数调用的堆栈
- 增加了保留字(比如protected、static和interface)
export 命令
模块功能主要由两个命令构成:export和import
export命令用于规定模块的对外接口,import命令用于输入其他模块提供的功能
一个模块就是一个独立的文件。该文件内部的所有变量,外部无法获取
外部能够读取模块内部的某个变量,就必须使用export关键字输出该变量
|
|
export命令除了输出变量,还可以输出函数或类(class)
|
|
export输出的变量就是本来的名字,但是可以使用as关键字重命名
|
|
export命令规定的是对外的接口,必须与模块内部的变量建立一一对应关系
|
|
function和class的输出,也必须遵守这样的写法
|
|
export命令可以出现在模块的任何位置,只要处于模块顶层就可以。如果处于块级作用域内,就会报错
|
|
import 命令
使用export命令定义了模块的对外接口以后,其他 JS 文件就可以通过import命令加载这个模块
|
|
import语句会执行所加载的模块
|
|
模块的整体加载
除了指定加载某个输出值,还可以使用整体加载,即用星号(*)指定一个对象,所有输出值都加载在这个对象上面
|
|
加载这个模块
|
|
上面写法是逐一指定要加载的方法,整体加载的写法如下
|
|
export default 命令
使用import命令的时候,用户需要知道所要加载的变量名或函数名,否则无法加载
用户肯定希望快速上手,未必愿意阅读文档,去了解模块有哪些属性和方法
为了给用户提供方便,让他们不用阅读文档就能加载模块,就要用到export default命令,为模块指定默认输出
|
|
其他模块加载该模块时,import命令可以为该匿名函数指定任意名字
|
|
export default命令用在非匿名函数前,也是可以的
|
|
下面比较一下默认输出和正常输出
|
|
有了export default命令,输入模块时就非常直观了,以输入 lodash 模块为例
|
|
对应上面代码的export语句如下
|
|
export default也可以用来输出类
|
|