ECMAScript 新特性
概述
1.通常看作JavaScript的标准化规范
2.实际上JavaScript是EVMAscript的扩展语言
3.ECMAscript只提供了最基本的语法 约定了方法 变量 语句等 不能应用实际功能开发
4.JavaScript语言本身指的就是ECMAscript
5.解决原有语法上的一些问题或不足
6.对原有语法进行增强
7.全新的对象、全新的方法、全新的功能
8.全新的数据类型和数据结构
9.ES6是表示泛指 准确叫ES2015 根据版本来迭代
let
1.产生作用域
2.变量不能被提升
const
1.恒量 不能放在两个声明语句中
2.声明过后 不能重新指向新的内存地址 可以修改内存空间中的数据
最佳实践:不用var,主用const,配合用let
ES2015 数组解构
1.定义变量名的地方修改为一个方括号 方括号中填写需要存放数据的变量名 根据位置分配数组所对应数值
const [foo,bar,baz] = arr
2.添加三个点表示提取从当前位置开始往后的所有成员 只能在最后一个成员中使用
const [foo,...rest] = arr
3.提取成员小于数组 只会取从前往后的数值 如果大于 就为undefined
4.可以提供默认值
const [more='default value] = arr
5.使操作数据变得简单
const path = '/fpp/bar/baz'
const [,rootdir] = path.split('/')
ES2015 对象结构
1.根据属性名去匹配 提取
const obj = {name:'zce',age:'18'}
const {name} = obj // 'zce'
2.可更改名字 避免冲突
const {name:objName} = obj
3.设置默认值
const {name:objName = 'jack'} = obj
const {log} = console
log('foo')
ES2015 模板字符串
1.反引号来标识 可输入换行符
2. 比字符串拼接更加直观 方便 可以是表达式 方法返回值 变量名
const name = 'tom'
const msg = `hey,${name} --- ${1+2} --- ${Math.random()}`
ES2015 带标签的模板字符串
1.定义一个标签 就是一个特殊的函数 调用这个函数
2.
const name = 'tom'
const gender = true
function myTagFunc(strings,name,gender){
console.log(strings,name,gender)
// 3
// return strings[0] + name + strings[1] + gender + strings[2]
}
const result = myTagFunc`hey,${name} is a ${gender}.`
按嵌入的表达式来分割过后静态的内容 以数组的形式 [ 'hey,', ' is a ', '.' ]
并且可以接收这个模板字符串中出现的表达式返回值 [ 'hey,', ' is a ', '.' ] tom true
可以接收这个标签的返回值 console.log(result) // hey,tom is a true.
3.给模板字符串进行加工
ES2015 字符串的扩展方法
1.includes() //是否包含
2.startsWith() //开头是否包含
3.endsWith() //结尾是否包含
ES2015 参数默认值
1.在没有传递参数时 使用的值
function foo(enable = true){
console.log(enable)
}
ES2015 剩余参数
1 以数组的形式接受参数 取代arguments接受无限参数
只可以使用一次 需要放到最后位
function foo(...args){
console.log(args)
}
ES2015 展开数组
console.log(...arr)
ES2015 箭头函数
1.简化函数写法 更加易读
function inc(num){
return num++
}
const inc = num => num++
2.不会改变this的指向
ES2015 对象字面量增强
const bar = '223'
const obj = {
foo:123,
bar,
fn(){
},
[Math.random()]:'31' //计算属性名 结果作为这个对象属性的属性名
}
ES2015 Object.assign
1.将多个源对象中的属性复制到一个目标对象中
const source1 = {
a:123,
b:123
}
const target = {
a:456,
c:456
}
const result = Object.assign(target,source1)
console.log(target) // {a:123,c:465,b:123} // result === target
ES2015 Object.is
0 == false
0 === false
Object.is(0,false)
Object.is(NaN,NaN) // true
NaN === NaN //false
ES2015 Proxy
1.监视某个对象的属性读写
const person = {
name:'zce',
age:20
}
const personProxy = new Proxy(person,{
//target:代理目标对象
//property:需要读的属性名
get(target,property){
return property in target ? target[property] : 'default'
},
//value:需要写入的属性值
set(target,property,value){
if(property === 'age'){
if(!Number.isInteger(value)){
throw new TypeError(`${value} is not an int`)
}
}
target[property] = value
},
deleteProperty(target,property){
delete target[property]
}
})
console.log(personProxy.name) // 'zce'
personProxy.gender = true // {name:'zce',age:20,gender:true}
delete personProxy.age // delete 出发条件
ES2015 Proxy 对比 defineProperty
1.defineProperty 只能监视对象的属性读写
2.Proxy 可以监听delete操作等
3.Proxy 可以更好的支持数组对象的监视
(1) 之前用重写数组的操作方法 vue(1-2)
(2) const list = []
const listProxy = new Proxy(list,{
set(target,property,value){
console.log('set',property,value) // set 0 100
target[property] = value
return true
}
})
listProxy.push(100)
4.proxy 是以非侵入的方式监管了对象的读写
const person = {}
Object.defineProperty(person,'name',{
get(){
console.log('name 被访问')
return person._name
},
set(value){
console.log('name 被设置')
person._name = value
}
})
person.name = 'jack'
console.log(person.name)
ES2015 Reflect
1.属于一个静态类
2.Reflect 内部封装了一系列对对象的底层操作 14个静态方法
3.Reflect 成员方法就是Proxy处理对象的,默认实现
const obj = {
foo:'123',
bar:'456'
}
const proxy = new Proxy(obj,{
get(target,property){
console.log('watch logic~')
return Reflect.get(target,property)
}
})
console.log(proxy.foo) // watch logic~ 123
4.提供了一套统一的用语操作对象的API
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))
ES2015 Promise
1.解决了 传统异步编程中回调函数嵌套过深的问题
ES2015 class
function Person(name){
this.name = name
}
Person.prototype.say = function(){
console.log(`hi, my name is ${this.name}`)
}
//改写
class Person{
constructor(name){ // 构造函数
this.name = name
}
say(){
console.log(`hi, my name is ${this.name}`)
}
}
const p = new Person('tom')
p.say()
ES2015 类的继承
class Student extends Person{
constructor(name,number){
super(name)
this.number = number
}
hello(){
super.say()
console.log(`my school number is ${this.number}`)
}
}
const s = new Student('jack','100')
s.hello()
ES2015 Set 数据结构
1.内部成员不予许重复
const s = new Set()
s.add(1).add(2).add(3).add(4).add(2)
console.log(s) // Set {1,2,3,4}
s.forEach(i => console.log(i))
console.log(s.size)
console.log(s.has(100))
console.log(s.delete(3))
s.clear()
const arr = [1,2,3,4]
const result = [...new Set(arr)] //快速转化为一个新的数组
ES2015 Map 数据结构
const m = new Map()
const tom = {name:'tom'}
m.set(tom,90)
console.log(m) // Map {{name:'tom'} => 90}
可以将任何数据作为对象的键值(key)
而通常的写法会自动转化为字符串的格式
const obj = {}
obj[{a:1}] = 'value' // obj['[Object Object]'] = 'value'
ES2015 Symbol
1.一种全新的原始数据类型 唯一的 避免属性名冲突
比如:一个对象要合并一个新的对象 但不知道其中是否有同名的情况
const obj = {}
obj[Symbol()] = '123'
obj[Symbol()] = '456'
console.log(obj) // {[Symbol()]:'123',[Symbol()]:'456'}
2.建立私有成员
const name = Symbol()
const person = {
[name]:'zce',
say(){
console.log(this[name])
}
}
// 外部没办法创建一个相同的Symbol
// person[Symbol()]
person.say() //只能调用这个普通对象的成员
3.改变toString()默认标签
const obj = {
[Symbol.toStringTag]:'XObject'
}
console.log(obj.toString()) // [object XObject]
4.获取Symbol 属性名
Object.getOwnPropertySymbols(obj) // 获取Symbol属性名
Object.keys(obj) 只能获取对象字符串属性名
ES2015 for…of循环
1.or 比较适合遍历普通的数组
2.or…in 比较适合遍历键值对
3.orEach,map 函数式的遍历方法
4. for…of 遍历任何数据
const obj = new Map()
obj.set('tom',90)
obj.set('lise',80)
const arr = [1,2,3]
for(const [key,value] of obj){
console.log(key,value) //obj 的键和值
if(item > 100){
break // 可通过break终止遍历
}
}
for(const item of arr){
console.log(item) //arr 的值
}
5.实现Iterable接口就是for…of的前提
const arr = ['foo','bar','baz']
const iterator = arr[Symbol.iterator]() //数组的迭代器对象
iterator.next() // {value:"foo",done:false}
iterator.next() // {value:"bar",done:false}
iterator.next() // {value:"baz",done:false}
iterator.next() // {value:undefined,done:true}
//实现
const todos = {
life:['吃饭','睡觉','打豆豆'],
learn:['语文','数学','英语'],
work:['喝茶'],
each:function(callback){
const all = [].concat(this.life,this.learn,this.work)
for(const item of all){
callback(item)
}
}
[Symbol.iterator]:function(){
const all = [...this.life,...this.learn,...this.work]
let index = 0
return {
next: function(){
return {
value: all[index],
done:index++ >= all.length
}
}
}
// for(const item of all){
// yield item
// }
}
}
for(const item of todos){
console.log(item) // iterator.next().value
}
6.核心:对外提供统一变量接口 让外部不用关心这个内部数据结构是怎么样的
ES2015 生成器
1.作用:避免异步编程中回调嵌套过深
function * foo(){
console.log('111')
yield 100 // 遇到yield暂停
console.log('222')
yield 200
console.log('333')
yield 300
}
const generator = foo() // 自动返回一个生成器对象
console.log(generator.next()) // 111 {value:100,done:false}
console.log(generator.next()) // 222 {value:200,done:false}
console.log(generator.next()) // 333 {value:300,done:false}
ES2016 概述
1.arr.includes(NaN) //可以查找NaN true
2.Math.pow(2,10) //指数运算
ES2017 概述
console.log(Object.value(obj))
const p1 = {
firstName:'lei',
lastName:'wang',
get fullName(){
return this.firstName + this.lastName
}
}
const descriptors = Object.getOenPropertyDescriptors(p1) // 获取对象完整描述信息
const p2 = Object.defineProperties({},descriptors)
//复制get set
console.log(p2.fullName)
3.在函数参数中添加尾逗号
4.Async/Await 利用promise的语法糖