新特性有四大类:
1、解决原有语法上的一些问题或不足
2、对原有语法进行增强
3、全新的对象,全新的方法,全新的功能
4、全新的数据类型和数据结构
一、Let,Const和块级作用域
在ES2015之前,只有全局作用域和函数作用域,现在可以声明Let和Const它们都属于块级作用域中的定义变量,并且不会声明提前。
for (let i = 0; i < 3; i++) {let i = 'foo'console.log(i)
}
二、数组和对象的解构
我们可以这样来解构数组和对象:
const [foo, bar, baz] = arr
const { name } = obj
三、模板字符串
模板字符串(`)支持换行,支持通过表达式${}插入一些参数。
function myTagFunc (strings, name, gender) {// console.log(strings, name, gender)const sex = gender ? 'man' : 'woman'return strings[0] + name + strings[1] + sex + strings[2]
}const result = myTagFunc`hey, ${name} is a ${gender}.`
我们也可以像这样给他定义一个标签,他会运行这个方法来替换其中的内容
四、字符串的一些扩展方法
const message = 'Error: foo is not defined.'console.log(message.startsWith('Error')message.endsWith('.')message.includes('foo')
)
五、functio参数默认值
我们可以通过function(value = true){}来传入一个默认值,带有默认值的参数一定要在入参的最后一位。
六、剩余参数
我们可以通过function(value,...args){}来传入一个剩余参数,这种参数只可以使用一次,并且只能在最后一位。
七、展开数组
const arr = [1,2,3]; consoel.log(...arr); // 1 2 3
八、箭头函数
普通函数 function (){} 箭头函数 () => {}; v => v + 1 ;
只有一条语句时,可以不加{},不加{}时,这一条语句会当做结果return出来。
另外箭头函数没有this声明,他会继续沿用外层的this指向。
九、ES2015中的对象字面量的增强
const bar = '345'
const obj = {foo: 123,// bar: bar// 属性名与变量名相同,可以省略 : barbar,// method1: function () {// console.log('method111')// }// 方法可以省略 : functionmethod1 () {console.log('method111')// 这种方法就是普通的函数,同样影响 this 指向。console.log(this)},// Math.random(): 123 // 不允许// 通过 [] 让表达式的结果作为属性名[Math.random()]: 123
}
十、Object扩展方法assgin与is
const obj = { name: 'global obj' };
const funObj = Object.assign({},obj);
console.log(0 == false // => true0 === false // => false+0 === -0 // => trueNaN === NaN // => falseObject.is(+0, -0) // => falseObject.is(NaN, NaN) // => true
)
十一、Proxy对象
const person = {name: 'zce',age: 20
}const personProxy = new Proxy(person, {get (target, property) {console.log('get', property)return target[property]},set (target, property, value) {console.log('set', property, value)target[property] = value}
})personProxy.name = 'jack'console.log(personProxy.name)
用于监听对象的属性修改和读取行为
十二、静态类Reflect
Reflect一共有十三种方法,整理了一些比较散乱的对象操作,用于替换以前的一些方法,在这里举3个比较常用的例子。
const obj = {name: 'zce',age: 18
}// console.log('name' in obj)
// console.log(delete obj['age'])
// console.log(Object.keys(obj))console.log(Reflect.has(obj, 'name'))
console.log(Reflect.deleteProperty(obj, 'age'))
console.log(Reflect.ownKeys(obj))
十三、Promise
用于更简洁遍历,能够链式调用的异步方法。
十四、Class 定义类
class Person {//构造函数constructor (name) {this.name = name}static of (name){return new Person(name)}say () {console.log(`hi, my name is ${this.name}`)}}
十五、Class的继承
class MyPromise extends Promise{//super代表父类super.resolve()
}
十六、Set方法
常用于面试题数组去重 const result = [...new Set([1,1,1,1,2,3,4])] // [1,2,3,4]
const s = new Set()
s.add(1).add(2).add(3).add(4).add(2)
s.forEach(i => console.log(i))
console.log(s.size)
console.log(s.has(100))
console.log(s.delete(3))
s.clear()
十七、Map数据结构
Map才是真正意义上的键值对集合,他可以用任意类型的值作为key,而对象只能用字符串作为key。
const m = new Map()
const tom = { name: 'tom' }
m.set(tom, 90)
console.log(m)
console.log(m.get(tom))// m.has()
// m.delete()
// m.clear()m.forEach((value, key) => {console.log(value, key)
})
十七、生成器函数 Generator
Generator 也被称为 异步方案的语法糖,
使用function * foo(){},yield作为断点代替return,再用foo.next()来继续执行。
以下是配合Promise的一个异步方案:
function ajax (url) {return new Promise((resolve, reject) => {var xhr = new XMLHttpRequest()xhr.open('GET', url)xhr.responseType = 'json'xhr.onload = () => {if (xhr.status === 200) {resolve(xhr.response)} else {reject(new Error(xhr.statusText))}}xhr.send()})
}function * main () {try {const users = yield ajax('/api/users.json')console.log(users)const posts = yield ajax('/api/posts.json')console.log(posts)const urls = yield ajax('/api/urls.json')console.log(urls)} catch (e) {console.log(e)}
}function co (generator) {const g = generator()function handleResult (result) {if (result.done) return // 生成器函数结束result.value.then(data => {handleResult(g.next(data))}, error => {g.throw(error)})}handleResult(g.next())
}co(main)
十八、Symbol数据类型
继String、Number、Null、Undefined、Boolean、Object之后的第七种数据类型
可防止扩展对象,属性名冲突问题,两个 Symbol 永远不会相等,可以使用 Symbol 为对象添加用不重复的键,实现对象的实现私有成员。
const name = Symbol()
const person = {[name]: 'zce',say () {console.log(this[name])}
}
十九、iterator迭代器
在一个对象中声明迭代器,可以对外给出一个遍历的接口。这也就是for...of的原理,我们可以将这个迭代器在任意对象中进行声明,然后赋予一个我们想要的方法,对外暴露一个循环的方法。内部挂载一个生成器函数Generator,外部其实是使用循环+next()的方式实现的。
const todos = {life: ['吃饭', '睡觉', '打豆豆'],learn: ['语文', '数学', '外语'],work: ['喝茶'],[Symbol.iterator]: function * () {const all = [...this.life, ...this.learn, ...this.work]for (const item of all) {yield item}}
}for (const item of todos) {console.log(item)
}