ECMAScript 新特性
let、const 与块级作用域
let
: 块级作用域中声明变量,变量声明前不允许访问。即不存在声明提升现象const
: 在let的特性的基础之上,多了只读属性。即const
声明的变量不允许重新赋值。
数组的解构
const arr = [100,200,300]
// 对应位置对应赋值
const [a,b,c] = arr // a=100 b=200 c=300
// 获取特定位置
const [,,e] = arr //300
// 获取数组剩余全部,注意...赋值只能在最后解构的最后位置使用
const [f,...rest] = arr; // f=100; rest = [200,300]
// 解构变量数量小于或者大于数组长度
const [foo] = arr; // 小于时从前往后提取,多出的不提取
const [z,x,c,more]; // more为undefined
// 设置默认值
const [default = 200] = arr; // 如果对应的位置没有值,default=200,对应位置有值,就赋值,此处default = 100
对象的解构
与解构数组规则类似,只不过是根据键名进行匹配赋值
const obj = {name:'abc', age: 18}
const {name, age} = obj; // name = 'abc', age = 18
// 当作用域中存在与解构对象键名重复的情况时,可以将解构出来的值重新赋值给另外一个变量
const {name:myname, age} = obj; // myname = 'abc' age = 18
模板字符串
-
支持多行字符串
-
通过插值表达式的方式(任何js语句),嵌入相应的值
-
带标签的模板字符串
const name = 'zxc';const gender = true;/*** strings 为模板字符串在变量位置分割成的所有字符串片段组成的数组* name 为模板字符串第一个变量* gender 为模板字符串的第二个变量* ... 以此类推,也可使用剩余语法,将所有的参数组合成一个按变量位置排序的数组*/function myTagFunc(strings, name, gender){ console.log(strings, name, gender) return 123}const result = myTagFunc`hey, ${name} is a ${gender}`
字符串的扩展方法
includes
是否包含给定字符startsWith
是否以给定字符开头endsWith
是否以给定字符结尾
剩余参数
// 只能使用在函数参数的最后的位置function(...rest){ console.log(rest) // rest为所有参数组成的数组}
展开运算符
const arr = [1,2,3];console.log(...arr); // 1,2,3
箭头函数与this
// 箭头函数不会改变this指向const person = { name: 'sam', sayHi: () => { console.log(this.name) }}person.sayHi() // undefined
对象字面量的增强
如果变量名和对象键名一致,就可以省略赋值
const bar = 123;const obj = { foo: '111', bar, [Math.random()]: '222' // 计算属性名,[]中的计算结果作为对象的键名}
对象扩展方法
Object.assgin()
将多个源对象中的属性复制到目标对象中,如果存在相同属性,目标对象中的属性值会被源对象中的属性值覆盖。该方法的返回值为目标对象
Object.assign(target, source1, source2, source3, source4,....)
-
Object.is()
判断两个值是否相等。可判断两个NaN是否相等。 -
Object.defineProperty()
-
Proxy
代理,对对象进行个性化的定制 vsObject.defineProperty()
- defineProperty 只能监听属性的读写
- Proxy 能够监视到更多的对象的操作,例如delete操作,in等
- Proxy 更好的支持数组对象的监视
- Proxy 是以非侵入的方式监管了对象的读写
const person = { name:'zxc', age: 18}const personProxy = new Proxy(person, { // target 为代理目标对象 // property 为要访问的目标属性 // value 为要设置的值 get(target, property){ console.log(target, property); return property in target ? target[property] : undefined } set(target, property, value){ console.log(target, property, value) }})personProxy.country = 'China'console.log(personProxy.name) // zxc'console.log(personProxy.gender) // undefined
Reflect
统一对象操作的API,静态类,不能通过new对象实例化Reflect
内部封装了一系列对对象的底层操作Reflect
成员方法就是Proxy
处理对象的默认实现
Promise对象
解决了回调地狱的问题。
静态方法
添加了静态成员的static的关键词
类的继承
extends
Set数据结构(与数组类似)
Set数据集合中的每一个值都是独一无二的,即Set数据集合中不存在重复的值
const s = new Set(); s.add(1).add(2).add(3) // 可实现链式调用 s.forEach(i => console.log(e)) // 遍历数据 for(let i of s){ console.log(i) } console.log(s.size) // 返回集合的大小 console.log(s.has(2)) // 判断是否存在给定值 console.log(s.delete(2)) // 删除指定值 s.clear() // 删除所有值
Map数据结构(与对象类似)
Map对象的键名可以为任何值,而普通对象的键名只能是string
。
const m = new Map();const tom = {name:'tom'};m.set(tom, 90)
Symbol 全新的原始数据类型
表示一个独一无二的值,从ES2015后,symbol可以作为对象的键名。最主要的作用就是为对象添加一个独一无二的属性名。
symbol
作为属性名,通过for...in、Object.keys()、JSON.stringify()
方法,是无法获取到的。可以通过Object.getOwnPropertySymbol()
方法获取- 创建同一个
symbol
,可以使用Symbol.for('key')
,key相同时,创建的symbol
数据就是相等的
for...of 循环
作为遍历所有数据结构(可迭代)的一种方式。默认可遍历数组,Set对象,Map对象等,对于对象来说,只要手动实现iterator内部逻辑即可。
Itrable
接口
// 实现可迭代器,Iteratorconst obj = { store : ['foo', 'bar', 'baz'], [Symbol.iterator]: function(){ let index = 0; const _this = this; return { next: function(){ return { value: _this.store[index], done: index++ >= self.store.length } } } }}for(let i of obj){ console.log(obj)}// 迭代器的作用// 对外部提供统一的接口,使外部不用关心内部的数据接口。对于js的语言来说,内部实现了统一的迭代器的接口,我们在使用的时候只需要关心实现迭代器的内部逻辑即可。
生成器 Generator
generator异步方案
- 语法上:生成器函数就是在普通的函数基础之上加上*号(
function\*foo(){}
) - 调用时,并不会立即执行该生成器函数,而是返回一个生成器对象。
- 执行得到的生成器对象的
next()
方法,该函数体才会开始执行。 - 函数内部可以使用
yield
关键词向外返回值,返回值为调用next()
方法后得到的对象的value值。另外,得到的对象还有一个done的值,用来表示该生成器函数是否已经全部执行完毕。yield
并不会结束生成器函数的执行,只是暂停该生成器函数的执行,当外部再次调用next()
方法的时候,生成器函数会从上次yield
代码的地方继续执行;另外如果调用next传参,该参数会作为yield语句的返回值,即在生成器函数内部,可以接受该值,同时该值也是这次调用返回对象的value值。 - 执行生成器的
throw()
方法,可以捕获生成器函数的异常(函数内部使用try…catch)