ES2015 俗称ES6 新特性
官网链接:
https://www.ecma-international.org/ecma-262/6.0/
新特性主要目的:
解决原有语法上的一些问题或者不足
let、const对原有语法增强
结构、展开、模板字符串等全新的对象、方法、功能
Promise、Proxy、Reflect等全新的数据类型、数据结构
set 、Map等作用域
全局作用域(旧版本)
函数作用域(旧版本)
块级作用域-
声明变量
var (旧版本,可实现变量声明的提升,不规范)
let
let声明的成员,删除变量声明的提升功能,只能在其块级作用域中被访问到const
const声明的成员是只读的,只能修改const声明变量的内容,不能改变变量内存地址。
全局 const声明的变量不会挂载到windows上。因为没有块级作用域环境。
const arr = [1,2,3]
arr.push(4)
// [1,2,3,4]
arr = [1,2]
// 报错
- 剩余参数( ... 的 rest 作用)
function (param1,param2,...params) {
statements
}
-
数组解构( ... 的 解构 作用)
[...arr]
...必须在最后一个元素前使用(越界会被解构成undefind)
[name='xiaoming',age] = arr 解构可赋值默认值
-
模板字符串
字符串换行直接换行实现
插值表达式`${js语句 1+2 或 变量 name} 这一句是换行后的内容。`
可以添加标签tag(实际是个函数)
includes()、startWith()、endsWith() 字符串扩展方法
-
参数默认值()
在需要默认值的形参后加默认值
function (name = xiaoming) {}
-
参数扩展,数组扩展
参数扩展 function (...args) {}
数组扩展 const arr = ['foo', 'bar', 'baz']
console.log.apply(console, arr)
=>旧
console.log(...arr)
=>新
-
箭头函数
fira Code 编程连体字体
不会改变this指向。没有自己的
this
,arguments
,super
或new.target
。箭头函数表达式更适用于那些本来需要匿名函数的地方,并且它不能用作构造函数。不会绑定普通函数的arguments对象
普通函数中
,this始终会指向调用者对象
可简化返回值的表达方式
-
对象字面量
value为值:当属性名和属性值名称相同时,可省略value
value为普通函数():可省略:与 function关键字
可以使用表达式或函数返回值作为属性名
const obj = {
name,
method () {
return "hello world"
},
[1+1] : "this is JS"
}
-
对象扩展
相同属性覆盖,不同属性扩展
Object.assign
const source1 = { a: 123, b: 123 } const source2 = { a: 123, b: 123 } const target = { b: 456, c: 456 } const newTarget = Object.assign(target, source1, source2) console.log(newTarget === target) // {a:123, c: 456, b: 123} // true // 应用🌰: function (obj) { // 复制,标识默认值 const newObj = Object.assign({},obj) newObj.name = obj.name || "defaultValue" }
-
Object.is
比较的三种形式:
方式 特点 == 比较前会进行类型转换(0==faluse 成立) === 推荐常用:严格模式(0===faluse 不成立,+0===-0 不成立,NaN === NaN 不成立) Object.is() +0===-0 成立,NaN === NaN 成立
-
Object.defineProperty 的加强版---> Proxy
为对象设置访问代理器,监听对象的读写等
二者比较:
类型 功能 具体表现 Proxy 监听范围 1. 可监视到属性的读写、调用,删除等操作
2. 可监听和重写数组方法(set 监听数组的写入 ,获取 下标 值)Object.defineProperty 监听范围 只能监听属性的读写 Proxy 监听形式 必须特定写法才能监听特定属性 Object.defineProperty 监听形式 Proxy是以非侵入方式监听,不必指定属性名
```js
Object.defineProperty(person,"name",{
set() {}
get() {}
})
```
-
Reflect
静态方法,不能实例化,有13个成员方法(14个废弃掉一个),是Proxy处理对象的默认实现,提供了一套统一操作对象的API
const person = { name: "xiaoming", sex: "man", age: 18 } const personProxy = new Proxy(person, { get(target, property) { // 监听的对象target,对象的属性property return Reflect.get(target,property) }, set(target, property, value) { // 监听的对象target,对象的属性property,属性的值value }, deleteProperty (target, property) { delete target[property] } }) delete personProxy.age Reflect.has(person, 'name') Reflect.deleteProperty(person, 'age') Reflect.ownKeys(person)
-
Promise
用于解决异步编程的新增解决方案
-
class 类,继承
class Person { contructor (name) { this.name = name } // 静态方法 static create (name) { return new Person(name) } // 实例方法 say () { } } class Student extends Person { contructor (name) { super(name) } say(){ super.say() } } const p1 = new Person('xiaoming') const p1 = Person.create('xiaoming') const s = new Person('xiaohong')
-
set
常用作数组去重
常见方法:clear()、add(value)
-
map
与对象的本质都是键值对集合。但是 对象的key必须为字符串或者Symbol,map的key可以使用任意数据类型
// Obj const obj = { name: "xiaoming" } Object.keys(obj) // ['name'] // Map const map = new Map() const name = {leader: 'xiaoming',member: 'xiaohong'} map.set(name,'xiaomingTeam') map.get(name) map.forEach(value,key) => { console.log(value,key) } // 'xiaomingTeam' {leader: 'xiaoming',member: 'xiaohong'}
-
Symbol
用于表示对象的一个独一无二的属性名(例如避免对象属性扩展时覆盖)
const name = Symbol() const person = { [name]: 'xiaoming', say(){ console.log(`hello ${this[name]}`) } }
获取Symbol:
Object.getOwnPropertySymbols(obj) 只能获取到Symbol属性名。
以下操作无法获取到Symbol:
- for in
- Object.keys(obj)
- JSON.stringify(obj)
只能获取到字符串属性名。
// .for 接收字符串。不是字符串也会转换成字符串 const s1 = Symbol.for('haha') const s2 = Symbol.for('haha') console.log(s1 === s2) // true Symbol.for('true') === Symbol.for(true) // true // 标识tag const obj = { [Symbol.toString]: 'NewObj' } console.log(obj.toString()) // [object NewObj]
-
for of 循环
用于遍历数组、伪数组、set、map
获取到的是数组中每一个元素(map获取到的是[key, value]数组),可以使用break终止循环,而forEach是不能break终止遍历的。
arr.some()
arr.every()
也是可以通过返回true或者false终止遍历的
ES2015提供了Iterable接口,能够使用for of遍历的数据结构。
数组、Map、set都实现了Iterable接口,挂载了iterator方法。iterator.next()可按顺序返回数据结构中的每一个元素,并通过done是否为true来标记循环的结束。
如何使对象 实现for of?
// 实现可迭代接口irerable
const obj = {
let index = 0
const originArr = ['hello', 'world','!']
[Symbol,iterator]: function() {
// 实现iterator
return {
next: function() {
// 实现 iterationresult
const result = {
value: originArr[index],
done: index++ >= self.originArr.length
}
return result
}
}
}
}
迭代器模式:实现统一迭代接口,不用关心数据内部数据结构
-
Generator
减少异步回调嵌套,提供更好的异步编程解决方案
// 实现了迭代接口协议 function * func() { return 100 } const result = func() console.log(result) // Object [Generator] {} console.log(result.next()) // {value: 100, done: true} // yield 惰性执行迭代 function * func2() { console.log("111") yield 100 console.log("222") yield 200 console.log("333") yield 300 } const generator = func2() console.log(generator.next()) // 111 // {value: 100, done: false} console.log(generator.next()) // 111 // {value: 100, done: false} // 222 // {value: 200, done: false} console.log(generator.next()) // 111 // {value: 100, done: false} // 222 // {value: 200, done: false} // 333 // {value: 300, done: false} function * createIdMaker () { let id = 1 while (true) { yield id ++ } } const idMaker = createIdMaker().next().value
// 实现可迭代接口irerable
const obj = {
let index = 0
const originArr1 = ['hello', 'world','!']
const originArr2 = ['a','b','c']
[Symbol,iterator]: function * () {
const all = [...originArr1, ...originArr2]
// 实现iterator
next: function * () {
// 实现 iterationresult
for (const item of all) {
yield item
}
}
}
}
for (const item of obj) {
console.log(item)
}
- ES Modules 模块化
ES2016(ECMAScript第七个版本)
-
数组的includes()
返回bool值,表达是否存在,也可检测NaN(indexof不能判断NaN(NaN是一个值))
-
指数运算符
2 ** 10 // 1024
ES2017 (ECMAScript第八个版本)
-
Object.values
所有值组成的数组
-
Object.entries
数组形式返回键值对 ['key', 'value']
-
Object.getOwnPropertyDescriptors
获取对象的属性完整信息
const p1 = { firstName : 'ming', lastName : 'xiao' get fullName () { return this.firstName + ' ' + this.lastName } } const descriptors = Object.getOwnPropertyDescriptors(p1) const p2 = Object.defineProperties({},descriptors) p2.firstName = 'hong' console.log(p2.fullName) // hong xiao
-
string.prototype.padStart / String.prototype.padEnd
字符串添加方法
-
在函数参数中添加尾逗号
const arr = [100, 200, 300,]
-
async 函数
配合await,可以彻底解决异步回调嵌套问题,本质上是Promise语法糖