ES6知识点整理

275 阅读9分钟

var let const

  • var:变量
 //1.可以重复声明,有预解析机制
   var a = 1;
   var a = 2;
 //2.作用域:全局作用域和函数作用域
  • let:变量
 //1.同一作用域下不能重复声明,不会进行预解析(必须先声明再使用)
   let a = 1;
   let a = 2;//报错
 //2.作用域:全局作用域和块级作用域( "{" "}"之间即为块级作用域)
  • const:常量
 //1.不能重复声明,不会进行预解析,必须赋值,不可修改(const保证的是指向的内存地址不可修改,因此const定义的引用类型只要指向的内存地址不改变,是可以更改引用类型的值)
 const arr = [];
 arr.push("holle");
 console.log(arr); //["holle"]
 //2.作用域:全局作用域和块级作用域

解构赋值

//对象解构赋值(遵守的规则:变量的名字必须和对象的key一致)
let obj = {
    a:"a",
    b:"b"
}
let {a,b} = obj;   //等同于 let a = obj.a;let b = obj.b;

//数组解构赋值(数组下标位置必须一样)
let arr = ["1","2","3"]
let [a,b] = arr

//字符串解构赋值(等同数组,位置一致)
let str = "abc"
let [a,b] = str

展开运算符...

//展开运算符:可以在函数调用/数组构造时, 将数组表达式或者string在语法层面展开;还可以在构造字面量对象时, 将对象表达式按key-value的方式展开

let arr1 = [1,2,3]
let arr2 = [0,...arr1,4]
consloe.log(arr2) //[0,1,2,3,4]

let obj1 = {
    a:1,
    b:2
}
let obj2 = {
    ...obj1,
    c:3
}
consloe.log(obj2)  //{a:1,b:2,c:3}
//实现对象的深拷贝  
let obj3 = {...obj1}
obj1.a = 10
console.log(obj3.a)  //  输出1

箭头函数

//箭头函数表达式的语法比函数表达式更简洁,并且没有自己的this,arguments,super或new.target。箭头函数不能用作构造函数
function fn(param){return param} //相当于 (param)=>param

//语法1:只有一个参数时"()"可以省略 param =>param
//语法2:函数体是表达式时 (param)=>{console.log(param)}
//语法3:加括号的函数体返回对象字面量表达式 param => ({a: "a"})
//语法4:不支持arguments,可使用剩余参数接收不定参 (param,...params)=>{console.log(params)}
//语法5:箭头函数不能作为构造函数,不能new
 
//this指向问题:
//普通函数:this指向函数调用者,默认情况下指向window;在严格模式下的函数调用下,this指向undefined;通过call,apply,bind绑定时,指向绑定的对象。
//箭头函数:没有自己的this,默认指向定义它时所在的对象的this,即父级的this。

//例:首先,在window下定义普通函数和箭头函数
 function fnA() {
     console.log(this)
 }
 let fnB = () => {
     console.log(this)
}
 fnA()   //window
 fnB()   //window
 //这时两个函数this都指向window,然后我们把箭头函数定义在函数内,方便改变父级this指向
let fnD;
let fnC = function () {
     console.log(this)
     fnD = () => {
         console.log(this)
     }
}
fnC()   //window
fnD()   //window

//这时调用两个函数,普通函数依旧指向调用它的对象,也就是window,箭头函数fnD的this继承了它父级fnC的this。
此时,我们改变fnC的指向,通过bind函数指向body

fnC = fnC.bind(document.body)
fnC()   //body
fnD()   //body
//此时打印结果也证明了,箭头函数的this指向始终与其父级this指向一致

数组新增方法

ps:静态方法:定义在构造函数上的方法为静态方法;实例方法:定义在构造函数和实例上的方法。 例:

        function Person() { }
        Person.sayName = function () {            //静态方法
            console.log("sayName")
        }
        Person.prototype.getName = function () {  //实例方法
            console.log("getName")
        }
        var xiaoming = new Person()
        xiaoming.getName()
        Person.sayName()
       
//Array.from:将一个类数组转换为真正的数组;
          //参数:arrayLike 类数组
          //返回值:新数组
          //使用:
                var obj = { 0: "a", 2: "b", length: 2 }
                var arr = Array.from(obj)
                console.log(arr) // ["a", undefined]
          //ps1:(类数组:有length属性,其索引为非负整数;不具有数组方法。)
          //ps2:类数组转数组也可使用...展开运算符
          
//Array.of:将一组值转换为数组;
          //参数:data1,...,dataN
          //返回值:新数组
          //使用:
               Array.of(1, 2) // [1, 2]
          
//arr.find:查找数组中第一个符合条件的元素;
          //参数:function 回调函数,回调接受3个参数(value,index[可选],array[可选])
          //返回值:符合条件的第一个元素,没有返回undefined
          //使用:
                let arr = [1,2,3,4]
                console.log(arr.find(item=>item==2)) //2
          
//arr.findIndex:查找数组中第一个符合条件的元素的下标;
          //参数:function 回调函数,回调接受3个参数(value,index[可选],array[可选])
          //返回值:符合条件的第一个元素的下标,没有返回-1
          //使用:
                let arr = [1,2,3,4]
                console.log(arr.findIndex(item=>item==2)) //1
          
//arr.flat:数组扁平化,如果原数组有空位会跳过;
          //参数:depth[可选] 要扁平的层级默认1,不管几维都转为一维可以传Infinity
          //返回值:新数组
          //使用:
                [1, 2, [3, 4]].flat()  //[1,2,3,4]

//arr.fill:用一个固定值填充数组;
          //参数:value用来填充的值 start[可选]开始下标 end[可选]结束下标
          //返回值:新数组
          //使用:
                [1, 2, 3].fill(1, 1, 2) //[1,1,3]

//arr.includes:判断数组中是否包含一个指定的值;
          //参数:value用来查找的值 index[可选]开始查找的位置,负数则表示倒数位置
          //返回值:Boolean
          //使用:
                [1, 2, 3].includes(2)     // true

字符串新增方法

//str.includes:判断字符串中是否包含一个指定的值;
          //参数:value用来查找的值 index[可选]开始查找的位置,负数则表示倒数位置
          //返回值:Boolean
          //使用:
                "123".includes("2")     // true
 
//str.startsWith:判断字符串是否已另一个字符串开始;
          //参数:str 要搜索的字符串 index[可选]开始查找的位置
          //返回值:Boolean
          //使用:
                "123".startsWith("1")     // true

//str.endsWith:判断字符串是否已另一个字符串结束;
          //参数:str 要搜索的字符串 length[可选]字符串长度,默认str.length
          //返回值:Boolean
          //使用:
                "123".endsWith("1")     // false

//str.repeat:重复原字符串;
          //参数:count 要重复的次数,小数会取整,小于-1报错
          //返回值:Boolean
          //使用:
                "123".endsWith("1")     // false

模板字符串

//模板字符串使用反引号 (` `) 来代替普通字符串中的用双引号和单引号。用(${ })将变量括起来,特殊字符需要加(\)进行转义。
//例:
    let money = 100
    let str1 = "本次消费"+money+"元"
    let str2 = `本次消费${money}元`
    console.log(str1,str2)    //本次消费100元 本次消费100元 //这两种字符串拼接方式等同

对象新增内容

//Object.is(value1,value2):判断两个值是否相等,与(===)行为一致,在其基础上增加了几处不同。如: +0不等于-0、NaN等于自身;
          //参数:value1,value2为比较的数据
          //返回值:Boolean
          //使用:
                Object.is(NaN,NaN)     // true
                
                
//Object.assign(target,...sources):将可枚举属性的值从一个或多个源对象复制到目标对象,相同key的值会覆盖;
          //参数:target目标对象,sources源对象
          //返回值:object
          //使用:
                let target = {name:"张三"}
                let source = {name:"李四",age:"17"}
                let tar = Object.assign(target,source)
                console.log(tar)       // {name: "李四", age: "17"}
                
                
//Object.keys(obj):返回一个所有给定目标对象自身可枚举属性名称的数组;
          //参数:obj目标对象
          //返回值:Array
          //使用:
                Object.keys({name:"李四",age:"17"})     // ["name","age"]

//Object.values(obj):返回一个所有给定目标对象自身可枚举值的数组;
          //参数:obj目标对象
          //返回值:Array
          //使用:
                Object.keys({name:"李四",age:"17"})     // ["李四","17"]


//Object.entries(obj):返回一个所有给定目标对象自身可枚举键值对的数组;
          //参数:obj目标对象
          //返回值:Array
          //使用:
                Object.keys({name:"李四",age:"17"})     // [["name","李四"],["age","17"]]
                
//新增对象属性:
//         1:如果属性名和变量名一致,可以简写
           let name = "张三"
           let obj = {
               name,
               age:"17"
           }
//         2:属性表达式
           let key1 = "name"
           let key2 = "age"
           let obj = {
               [key1]:"张三"
           }
           obj[key2] = "17"

面向对象新特性

es6推出了class关键字用来定义一个类,是构造函数的一个语法糖。class定义的类必须有一个名为constructor()的函数,如果没设就会默认添加一个,这个函数中的this指向生成的实例。class声明的类具有暂时性死区,必须先定义在使用

\\    书写格式
      class Person {     // class 类名(首字母大写约定)
            constructor(name, age) { // constructor(实例化传入的参数)
                this.name = name
                this.age = age
            }
            sayName() {
                console.log(`name is ${this.name}`)   //方法名(){函数体}  函数直接挂载到原型上
            }
            static maxAge = 200             //添加静态属性   static 属性名 = 属性值    静态属性无法被实例使用
            static sayMaxAge() {             //添加静态方法   static 方法名(){方法体}   静态方法无法被实例调用
                console.log(`maxAge is ${this.maxAge}`)
            }
            get _age() {                   //原型上不能定义属性,可以通过get和set设置
                return this.age
            }
            set _age(value) {
                this.age = value
            }
        }
        let person = new Person("张三", "17")
        person.sayName()    //name is 张三
        Person.sayMaxAge()  //maxAge is 200
        person.age = 20
        console.log(person.age)  //20
        console.log(person)  //20
        //继承
        class Student extends Person{  // 子类名 extends 父类名
          constructor(name,age,scores){
               super(name,age)    //为子类生成this对象,将父类属性和方法赋值到子类this上,不调用会报错
               this.scores = scores
          }
          sayScores(){
            console.log(`scores is ${this.scores}`)
          }

        }
        let student = new Student("李明","20","600")
        student.sayName()    //name is 李明
        student.sayScores()    //scores is 600
        Student.sayMaxAge()  //maxAge is 200
        student.age = 30
        console.log(student.age)  //30

proxy

ES6中提供了proxy,proxy在目标对象的外层搭建了一层拦截,外界对目标对象的某些操作,必须通过这层拦截。

        var proxy = new Proxy(target, handler)
  • target:目标对象(可以是任何类型)
  • handler:配置对象,里面定义各种代理行为

例:

        let target = {
            name: "张三",
            age: 26,
        }
        let proxyTarget = new Proxy(target, {
            get:function(target, key) {
                return target[key]
            },
            set:function(target,key,value){
               target[key] = value
            }
        })
        proxyTarget.age = 20
        console.log(proxyTarget.age)//20
        console.log(target.age)//20

此例子中,读取和设置proxyTarget的属性会经过get跟set方法。此外handler还提供多种方法对target实现代理:

  • get(target, key, receiver):代理对象读取属性    target:目标对象    key:对象属性    receiver:代理前的proxy对象 可选参数

  • set(target, key, value, receiver):代理对象属性赋值    target:目标对象    key:对象属性    value:设置的属性值    receiver:代理前的proxy对象 可选参数

  • has(target, key):代理对象属性是否存在    target:目标对象    key:对象属性

  • deleteProperty(target, key):代理对象deleteProperty()    target:目标对象    key:对象属性

  • defineProperty(target, key, desc):代理对象defineProperty()    target:目标对象    key:对象属性    desc:设置的属性值和相关配置

  • construct(target, args):代理实例new命令    target:目标对象    args:构造函数的参数

  • apply(target, object, args):代理对象属性赋值    target:目标对象    object:上下文对象(this)    args:参数s数组

  • getOwnPropertyDescriptor(target, key):代理对象getOwnPropertyDescriptor()    target:目标对象    key:对象属性

  • getPrototypeOf(target):代理对象读取原型    target:目标对象

  • isExtensible(target):代理isExtensible()    target:目标对象

  • ownKeys(target):代理对象读取属性    target:目标对象

  • preventExtensions(target):代理对象preventExtensions()    target:目标对象

  • setPrototypeOf(target, proto):代理对象setPrototypeOf()    target:目标对象    proto:原型