简介
ES6是ECMA组织为JavaScript制定的第6个标准版本(es6=es2015),相关历史可查看《ES6-ECMAScript6简介》。
1.变量声明
相同点:都没有预解析(变量提升),都不能重复定义相同变量,都有块级作用域,都不挂在到window对象中,都有暂时性死区。
let:变量 声明时可以不赋值,无论是基本类型还是引用类型都可以改变。
const(优先使用):常量 声明时必须赋值,一旦定义不能被改变,但是引用类型可以改变(不变的是栈中地址,改变的是堆中数据,若想不让其改变可以使用Object.freeze())
2.箭头函数
参数 => 函数体 () => { } 省略了关键字function
一个形参可以省略小括号,
没有argument,
this指向:指向父级作用域的调用者,与父级作用域this相同(与函数声明时所在作用域下的this相同)
函数体只有一行的情况下可以简写(去掉大括号和return),
不能用call等方法改变this的指向,
不能用于构造函数
const fun = function() {} //es5
const fun = () => {} //es6
const obj = {
name : 'wangdachui',
showName: () => {
console.log(this === obj); //false
console.log(this);
},
showName1: function() {
console.log(this === obj); //true
console.log(this);
},
showName2() {
console.log(this === obj); //true
console.log(this);
},
}
obj.showName()
obj.showName1()
obj.showName2()
3.模板字符串
可以换行书写,变量拼接,调用函数
实现换行
let str1 = `hello,
es6 demo up!'
console.log( str1)
使用表达式获取变量值
let name = "Mike"
let age = 20
let str2 = `hello,${name} ,age is ${age+1}`
console.log( str2)
hello,Mike ,age is 21
调用方法
function f1() {
return "hello f1"
}
let str3 =`demo,${f1()}
console.log( str3)
demo,hello f1
4.解构赋值
解构数组:const [变量1,变量2,···] = [数据1,数据2,···]
const arr = [10,20,[30,40,[50]]]
const [a,b,[c,d,[e]]] = arr
const list = ['aaa','bbb','ccc'];
const [aa,bb] = list;
console.log(aa,bb); // aaa, bbb
let list = [ 'aaa' , [ 'bbb' , 'ccc' ] , 'ddd' ];
let [ aa , [ bb ] ] = list;
console.log(aa,bb); // aaa , bbb
//设置默认值
const list = [aaa,'bbb','ccc'];
const [aa,bb,cc,dd = '大锤'] = list;
console.log(aa,bb,cc,dd); // aaa, bbb
//通过...语法将数组中的其余元素赋值给一个特定的变量
let list = ['aaa','bbb','ccc'];
let [aa,...bb] = list;
console.log(aa); // aaa
console.log(bb); // ['bbb','ccc']
//混合结构
let node = { (混合结构)
name:'foo',
loc:{
start:{
line:1,
column:1
}
},
range:[0,3]
}
let {
loc:{start:{line}},
range:[startIndex]
} = node;
console.log(line); // 1
console.log(startIndex); // 0
解构对象:const {key1,key2,···} = {键值对1,键值对2,···}
let obj = {
firstName:'wang',
lastName:'dachui',
age:22
}
let {firstName,age} = obj;
console.log(firstName); // wang
console.log(age); // 22
//别名
let {age: age111} = obj
console.log(age111)
//默认值
let {firstName,age1=11} = obj;
console.log(firstName); // wang
console.log(age1); // 11
//嵌套对象解构
const student = {
name:'jsPool',
age:20,
scores:{
math:95,
chinese:98,
english:93
}
}
function showScore(student){
const { name,scores:{ math = 0,chinese = 0, english = 0}} = student;
console.log('学生名:' + name);
console.log('数学成绩:' + math);
console.log('语文成绩:' + chinese);
console.log('英语成绩:' + english);
}
showScore(student)
5.对象简写
键和值相同时,可以简写为一个
对象内函数简写:f1:function () { } === f3 () { }
传统方式定义的方法
const person1 = {
sayHi :function(){
console.log( "Hi")
}
}
调用
person1. sayHi()
// es6
const person2 = {
sayHi(){
console.log( "Hi")
}
}
6.扩展运算符
对象
//对象合并
let p1 = {name:12,age:2}
let p2 = {name1:12,age1:2}
let p3 = {...p1,...p2}
console.log(p3);
let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };
console.log(z) // {a: 3, b: 4}
对象克隆
const copyobj = {...p1} //基本类型深拷贝,引用类型为浅拷贝
console.log(copyobj)
数组
const arr = [1,2,3,3]
const arr1 = [4,5,6]
数组合并
const arr3 = arr.concat(arr1)
console.log(arr3)
const arr4 = [...arr,...arr1]
console.log(arr4)
数组克隆
const copyArr = [...arr] //基本类型深拷贝,引用类型为浅拷贝
将伪数组转为真数组
const newarr = new Set(arr)
console.log(newarr)
const realarr = [...newarr]
console.log(realarr)
7.rest参数
arguments是伪数组,rest是真正的数组(利用...扩展运算符),可以使用数组的一些方法。
//es5
function data() {
console.log(arguments)
}
data('aaa','bbb') //['aaa','bbb']
//es6
function data1(...args) {
console.log(args)
}
data1('ccc','ddd') //['ccc','ddd']
let fun = (...args) => {
console.log(args)
}
fun('ccc','ddd') //['ccc','ddd']
8.promise
const promiseObj = new Promise( (resolve,reject) => {
setTimeout(() => {
let status = true
if(status) {
resolve('数据读取成功')
}else{
reject('数据读取失败')
}
},1000)
})
promiseObj.then(value => {
console.log(value)
},reason => {
console.log(reason)
})
9.Set,Map
ES6 提供了新的数据结构 Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。
Set本身是一个构造函数,用来生成 Set 数据结构。
Set数据结构,伪数组,可以根据它的特性进行数组去重,集合的一些操作。
//set api
//元素个数
let setData = new Set(['qqq','www','eee'])
console.log(setData.size)
//添加元素
setData.add('aaa')
console.log(setData)
//删除元素
setData.delete('qqq')
console.log(setData)
//检查是否有该元素
console.log(setData.has('www'))
//清除所有成员,没有返回值。
setData.clear()
console.log(setData)
//集合-取交集
let arr = [1,2,3,4,4,4,5,5,6]
let arr1 = [5,6,7,8,9,8,9,9]
let res = [...new Set(arr)].filter(item => new Set(arr1).has(item))
console.log(res)
//集合-取差集
let arr = [1,2,3,4,4,4,5,5,6]
let arr1 = [5,6,7,8,9,8,9,9]
let res = [...new Set(arr)].filter(item => !(new Set(arr1).has(item)))
console.log(res)
//集合-并集
let arr = [1,2,3,4,4,4,5,5,6]
let arr1 = [5,6,7,8,9,8,9,9]
let res = [...new Set([...arr,...arr1])]
console.log(res)
//Array.from或者...扩展运算符可以将 Set 结构转为数组。
const items = new Set([1, 2, 3, 4, 5]);
const array = Array.from(items);
const array = [...items];
Map数据结构,类似对象也是键值对的集合,但是键不仅限于字符串。
Object 结构提供了“字符串--值”的对应,Map 结构提供了“值--值”的对应,是一种更完善的 Hash 结构实现。
const m = new Map();
const o = {p: 'Hello World'};
m.set(o, 'content')
m.get(o) // "content"
m.has(o) // true
m.delete(o) // true
m.has(o) // false
10.class
ES6 中支持 class 语法,不过,ES6的class不是新的对象继承模型,它只是原型链的语法糖表现形式。 函数中使用 static 关键词定义构造函数的的方法和属性:
es5构造函数
function phone(brand,price){
this.brand = brand
this.price = price
static name1 = '静态成员'(属于类不属于实例对象)
}
Phone.prototype.call = function(){
console.log('打电话')
}
let huawei = new Phone('华为',1111)
huawei.call()
console.log(huawei)
es6 class
class Phone {
constructor(brand,price){
this.brand = brand
this.price = price
}
call(){
console.log('打电话')
}
}
let huawei = new Phone('华为',1111)
huawei.call()
console.log(huawei)
class Student {
constructor() {
console.log("I'm a student.");
}
study() {
console.log('study!');
}
static read() {
console.log("Reading Now.");
}
}
console.log(typeof Student); // function
let stu = new Student(); // "I'm a student."
stu.study(); // "study!"
stu.read(); // "Reading Now."
类中的继承和超集:
class Phone {
constructor() {
console.log("I'm a phone.");
}
}
class MI extends Phone {
constructor() {
super();
console.log("I'm a phone designed by xiaomi");
}
}
let mi8 = new MI();
extends 允许一个子类继承父类,需要注意的是,子类的constructor 函数中需要执行 super() 函数。 当然,你也可以在子类方法中调用父类的方法,如super.parentMethodName()。 在 这里 阅读更多关于类的介绍。
有几点值得注意的是:
- 类的声明不会提升(hoisting),如果你要使用某个 Class,那你必须在使用之前定义它,否则会抛出一个 ReferenceError 的错误
- 在类中定义函数不需要使用 function 关键词
持续更新...