ECMAScript2015即ES6已经发布很久了,做过的很多项目也都使用上了其中的一些新特性,但是我依然觉得自己对于它没有一个完整的认知,因而写此博客帮助梳理归纳,有不对的地方欢迎指出。
ECMA2015的意义
- 解决了原有语法上的一些问题和不足
- 对原有语法进行了增强
- 发布了全新的对象、方法和功能
- 定义了全新的数据类型和数据结构
ECMAScript2015新特性
ECMAScript概述
- 提供了最基本的语法,通常被看做是JavaScript的标准规范
- 其实JavaScript是ES的拓展.
- 浏览器运行环境中的JavaScript包含了ECMAScript 和 Web APIs(BOM 和 DOM)
- Node.js运行环境中的JavaScript包含了ECMAScript 和 Node APIs(fs/net/etc等)
- ECMAScript2015就是我们通常说的ES6,6是版本号,ES6之后官方是用年份来命名的
ECMA2015的意义
- 解决了原有语法上的一些问题和不足
- 对原有语法进行了增强
- 提供了全新的对象、全新的语法和全新的功能
- 全新的数据类型和数据结构
块级作用域
- 使用let const声明的变量只在块级作用域内起作用
- var声明的变量创建和初始化过程会被提升,可以在声明之前使用,不会报错;let 声明的变量只会提升创建过程,存在暂时性死区,所以变量不能在声明之前使用,会在控制台报错
- var 声明的变量可以随意改变,不存在块级作用域,let const 声明的变量只能在对应块级作用域内有效
- const声明的变量不能改变栈中的值,如果是普通数据,则不能改变值,如果是引用类型数据,则不能改变引用地址,但是数据的属性值可以改变.
- 用let,const在全局作用域中声明的变量不会挂载到window对象上.
- const声明变量的时候必须赋值
数组的解构
const [one,two,three] = [1,2,3]
console.log(one,two,three) // 1 2 3
const [a, , c] = [1,2,3]
console.log(a,c) // 1 3
const [x,y,z] = [1,2]
console.log(x,y,z) // 1,2,undefined
对象的解构
const {name} = {name: 'lisi'}
console.log(name) // lisi
const {name: objName} = {name: 'lisi'}
console.log(objName) // lisi
模板字符串
- 插值表达式
- 标签函数
const name = 'lisi'
// result 等于标签函数的返回值,可以用于配置字符串结果
// strings是由分割的字符组成的数组
function tagFunction (strings, name) {
return 'hello'
}
let result = tagFunction`hello, ${name}`
字符串的扩展方法
- startWith
- endWith
- includes
函数传参的扩展
- 参数可以设置默认值,设置默认值的参数必须放在最后面
- 剩余参数,…args获取到剩余参数,当我们不知道具体传参,同样只能放在最后
箭头函数
- 相比传统函数,简化了代码
- 可以自动返回值,不写花括号的时候
- 不会改变this指向,声明时this指向谁,调用时就指向谁
对象字面量增强
- 属性声明与赋值代码简化
const name = 'lisi'
const obj = {
gender: 0,
name
}
Object.asign
Object.asign(target, obj, obj, ...)
Object.is
- 判断值是否相等
- 可以区分-0和+0
- 判断NaN与NaN是否相等时返回true
Proxy
- 代理(可以理解为门卫),监听对象的读写
- vue3.0中实现响应式的功能
- 功能比Object.defineProperty更强大
- 可以监听delete
- 可以监视数组
- 以非侵入的方式去监听
Reflect
- 是一个静态类,不使用new声明实例
- 封装了13个对象的基本操作API
- 统一对象操作方法
- 推荐以后开发中多多使用,可以作为开发规范
- 静态方法: has/deleteProperty/ownKeys
const obj = {name: 'lisi'}
const name = Reflect.get(obj,'name')
console.log(name) // lisi
promise
- 主要解决异步回调函数嵌套过深的问题
class类
- 可以声明静态方法和属性,在实例中访问不到
- 继承: extends
set
- 集合,不允许有重复值
- 可用于数组去重
- 静态方法: has/delete/clear
// 将set转化为普通数组的方法
Array.from(set)
const arr = [...set]
map
- 与普通对象的区别是可以使用任意类型数据作为键
- 真正实现了键值对集合
Symbol
- 创建的每一个值都是唯一的,无论传入的参数是否相同.
- 作为obj的属性名时,无法通过中括号获取到,可以作为私有属性
- 目前主要用于给对象添加独一无二的属性名
- Symbol.for,可以针对某个字符创建,这样相同的字符得到的是相同的Symbol对象,相同的的字符串会得到相同的symbol对象
- Symbol.toStringTag,可以改变对象调用toString的结果
const obj = {
[Symbol.toStringTag]: '[object symbolTag]'
}
console.log(obj.toString()) // [object symbolTag]
- obj.getOwnPropertySymbols()可以拿到对象的Symbol属性名
for … of
-
for循环,for…in, forEach …多种循环方法
-
以后会作为遍历所有,拿到的是数组元素而不是下标
-
可以随时用break去终止遍历
-
伪数组也可以被for…of循环遍历
-
set map也可以被循环遍历
-
无法遍历普通对象,object is not iterable
-
es2015提供了Iterable接口,实现Iterable接口就可以被for…of循环遍历
迭代器模式
- 为数据提供统一的遍历方法,无需关心数据结构,即可遍历到数据的每一项
- 任何数据结构只要在内部定义了iterator接口,即可被for…of循环遍历
const todos = {
[Symbol.iterator]: function () {
cosnt all = []
let index = 0;
return {
next: function () {
return {
value: all[index]
done: index ++ >= all.length
}
}
}
}
}
生成器函数
- 解决异步回调嵌套过深的问题
- 调用next得到的是yield后面的数据
function * foo () {
console.log(111)
yield 111
console.log(222)
yield 222
console.log(333)
yield 333
}
const generator = foo()
generator.next()
generator.next()
generator.next()
generator.next()
// 生成器搭配迭代器使用
const todos = {
[Symbol.iterator]: function () {
cosnt all = []
let index = 0;
for (let item of all){
yield item
}
}
}
// 发号器
function * createIdMaker () {
let id = 1;
// 不会形成死循环,yield每次执行过后都会停止,知道下次next的调用
while(true){
yield id ++ ;
}
}
ES modules
ES2016(ES7)
- 指数运算符: 2 ** 10 等同于Math.power(2, 10)
- 数组的includes方法, 返回值为bool类型,可以用于查找NaN,indexOf无法查找NaN
ES2017(ES8)
- object.values(): 与Object.keys方法类似
- Object.entries():
- Object.getOwnPropertyDescription: 复制只读属性,get set
- 字符串的padStart,padEnd
- 函数参数最后一位可以添加尾逗号
- async await