ES6

ECMA6Script

ECMAScript 6,简称ES6,是JavaScript语言的一次重大更新

由于VUE3中大量使用了ES6的语法,所以ES6成为了学习VUE3的门槛之一

  • 更加简洁:
  • 更强大的功能
  • 更好的实用性

ES6的变量和模板字符串

ES6中新增了letconst,用来声明变量,使用的细节存在差异


let和var的区别
  • let不能重复声明
var i = 10
var i ="hello"

let j = 10
let j = "hello"//报错,let不能重复声明  Uncaught SyntaxError: Identifier 'j' has already been
  • let有块级作用域,非函数的花括号遇见let也会有块级作用域
{
    var i = 10
    let j = 10
}
console.log(i) //10
console.log(j) //变量j未被定义  Uncaught ReferenceError: j is not defined
  • let不会预解析进行变量提升
console.log(a) //undefined
var a =10

console.log(j) //变量j未被预解析 Uncaught ReferenceError: Cannot access 'j' before initialization
let j =10
  • let定义的全局变量不会作为windows(Bom编程)的属性
var a = 10 //a会变成window的属性
console.log(window.a) //10

let b =10
console.log(window.b) //undefined
  • let在es6中推荐优先使用

const

const中文释义:常数;恒量

const就是不可修改的let

类似于java中被final修饰的数(常量)

  • const的值不可被修改
const a = 10
a = 20  // Uncaught TypeError: Assignment to constant variable.
  • const的值不可为空
const a //Uncaught SyntaxError: Missing initializer in const declaration
  • const可以设置常量值
const PI = 3.14;
  • const内容为对象时,不可以修改其值的本质是不可修改引用,其内容还是可以发生变化的
const techers = ["张老师", "王老师", "李老师"];
//techers = ["","",""] //无法修改 Uncaught TypeError: Assignment to constant variable.
techers.push("赵老师");
console.log(techers); //['张老师', '王老师', '李老师', '赵老师']

模板字符串

模板字符串用以处理字符串换行和字符串拼接问题

" "或者' '中的传统字符串是不支持多行

``中的字符支持多行且拼接变量可以直接用${}的方式

` 反单引号(backquote),又称反引号,是西文字符中的附加符号,主要用于计算机领域

<script>
	let city = "长春";
	let str = 
`<ul>
    <li>${city}</li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
</ul>`;
	console.log(str);
</script>

${变量}在字符串中的使用是获取变量内容并进行字符串拼接

${表达式}在JSP中是EL表达式,作用是获取表达式的值


ES6的解构表达式

解构数组和对象
<script>
    let arr = [11,22,33,44]
    //解构表达式取出数组中的元素
    let [a,b,c,d,e = 10] = arr
    console.log(a,b,c,d,e) //11 22 33 44 10


    let person = {
        name : "xiaobai",
        age : 18
    }
    //使用解构表达式获取对象的属性值
    let {name,age} = person
    console.log(name,age)
</script>

当使用解构表达式解构对象时,其属性值的获取是根据属性名获取的(不同于数组的索引)

所以无法给非属性名的变量赋值解构

let person = {
    name : "xiaobai",
    age : 18
}
//使用解构表达式获取对象的属性值
let {x,y} = person
console.log(x,y) //undefined undefined

解构表达式作为方法的形参
<script>
    let arr = [11,22,33,44]
    //解构表达式作为形参使用
    function showArr([a,b,c=10]){
        console.log(a,b,c)
    }
    showArr(arr)
</script>

ES6的箭头函数

ES6允许使用"箭头"函数,语法类似Java中的Lambda表达式

在java中,lambda表达式多用于结合函数式接口实现匿名内部类的功能,而js中多用于定义函数(方法)

其中括号内是形参,大括号是执行体,而js是弱类型无需函数返回类型和形参类型,函数名即为赋值给的变量名

<script>
    let fun1 = function(){} //普通的函数声明
    let fun2 = () => {} //箭头表达式(lambda)
    let fun3 = (x) => { return x+1 }
    let fun4 = x => { return x+1 } //当参数只有一个的时候 小括号省略
    let fun5 = x => console.log(x) //当执行语句只有一条的时候 大括号省略
    let fun6 = x => x+1 //当执行语句只有一条且时return时 大括号和return都省略
</script>

箭头函数中的this问题

箭头函数中,没有自己的this

箭头函数中的this时外层上下文环境的this

let person ={
    name : "xiaobai",
    showName:function(){
        console.log(this.name)
    },
    viewName:() => {
        console.log(this.name)
    },
    viewThis:() =>{
        console.log(this)
    }
}
person.showName() //xiaobai
person.viewName() //空白
person.viewThis() //Window对象

每当使用箭头函数时,其this为上一层对象,如果实在找不到this就直接打印出来


rest和spread

rest剩余参数

rest中文释义:剩余的

rest在js的用法相当于java的可变参数,其在形参中的最后使用且只能有一个,写法是... arr

无论参数的类型是什么,有多少,都以数组的形式接受剩余参数

let fun1 = (... arr) => { console.log(arr) }
fun1(1,2,3,4,5,6,7,8,9,"str")

spread实参传递

spread中文释义:扩散;展开

和rest的写法相同,在调用方法时作为实参使用

在传入实参时将数组内容扩散展开分别为形参赋值

let arr = [1,2,3]
let fun = (a,b,c) => {
    console.log(a,b,c) 
}
fun(arr) //[1, 2, 3] undefined undefined
fun(...arr) //1 2 3

在形参中使用解构表达式,直接将数组作为实参也能完成此功能


spread合并数组

spread可以快速合并数组

let a = [1,2,3]
let b = [4,5,6]
let c = [7,8,9]
let d = [...a,...b,...c]

console.log(d) //[1, 2, 3, 4, 5, 6, 7, 8, 9]

spread合并对象

spread可以快速合并对象

注:如果有重名对象,后者会覆盖前者

let person1 = {name:"张三",age:"10"}
let person2 = {name:"小白",age:"18",gender:"boy"}
let person3 = {salary:"3000"}
let person4 = {...person1,...person2,...person3}
console.log(person4)//{name: '小白', age: '18', gender: 'boy', salary: '3000'}

对象创建的语法糖

ES6中新增了对象创建的语法糖,支持了class extends constructor等关键字,让ES6的语法和面向对象的语法更加接近

class Person{
    //属性
    name;
    #age;
    //getter/setter
    get name(){
        return this.name
    }
    set name(name){
        this.name = name
    }
    get setage(){
        return this.#age
    }
    set setage(age){
        this.#age = age
    }
    //实例方法
    eat(food){
        console.log(`${this.age}岁的${this.name}正在吃${food}`)
    }
    //静态方法
    static sum(a,b){
        return a+b
    }
    //构造方法
    constructor(name,age){
        this.name = name
        this.#age = age
    }
}

js中没有private关键字,要在私有属性前加#,但要注意的是,所有对此属性的操作时,属性名都有#


类的方法

在调用get/set方法时和调用普通的实例方法不同,相当于直接.属性赋值的形式调用

let person = new Person()
person.name = "xiaobai"
person.setage = 18 //调用set方法
console.log(person) //Person {name: 'xiaobai', age: 18}
//私有属性无法通过.属性名的方式访问
console.log(person.#age)//Uncaught SyntaxError: Private field '#age' must be declared in an enclosing class
//调用实例方法
person.eat("火锅") //18岁的xiaobai正在吃火锅
//调用静态方法
console.log(Person.sum(10,20)) //30
//调用构造方法
let person1 = new Person("xiaoming",20)
console.log(person1)

类的继承

在ES6的语法糖中,继承也是可以使用的

class Student extends Person{
    score
    study(){
        console.log(`${this.getage}岁的${this.name}正在努力学习,考试获得了${this.score}分`)
    }
    constructor(name,age,score){
        super(name,age)
        this.score = score
    }
}
let stu = new Student("xiaobai",18,100)
stu.study() //18岁的xiaobai正在努力学习,考试获得了100分

对象拷贝的语法糖

浅拷贝

浅拷贝是多一个引用指向同一个对象

let arr = [1,2,3]
let arr2 = arr
arr[0] = 100
console.log(arr2) // [100, 2, 3]

person = {name : "xiaobai",age : 18}
person2 = person
person.name = "xiaohei"
console.log(person2) //{name: 'xiaohei', age: 18}

深拷贝

深拷贝是完全一个全新的对象

可以通过spread展开赋值

let arr = [1,2,3]
let arr2 = [...arr]
arr[0] = 100
console.log(arr2) // [1, 2, 3]

person = {name : "xiaobai",age : 18}
person2 = {...person}
person.name = "xiaohei"
console.log(person2) //{name: 'xiaobai', age: 18}

还可以通过json字符串的转换来给对象重新赋值

先将对象转为JSON串,再转换回变量

person = {name : "xiaobai",age : 18}
person2 = JSON.parse(JSON.stringify(person))
person.name = "xiaohei"
console.log(person2) //{name: 'xiaobai', age: 18}