ES6

107 阅读5分钟

简介

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 关键词

持续更新...