ES6语法

68 阅读10分钟

一、定义变量

(1)let

  • let 声明的变量只在 let 命令所在的代码块内有效。

(2)const

  • const 声明一个只读的常量,一旦声明,常量的值就不能改变

(3)let/constvar的区别

  • ①预解析

    • var会进行预解析
    • letconst不会,必须在定义后使用变量
     console.log( n1 );//undefined
     var n1 = 666;
     console.log( n2 ) // 报错
     let n2 = 888;
     console.log( n3 ) // 报错
     const n3 = 888;
    
  • ②重复变量名

    • var可以定义重复变量名,重复定义没有意义
    • letconst不能定义重复变量名
     var n = 6;
     var n;
     console.log( n )
     let n1 = 7;
     // let n1 = 8; // 报错
     const n2 = 7;
     // const n2 = 8; // 报错
    
  • ③块级作用域

    • var是没有块级作用域,只会被私有作用域限制使用范围(函数内)
    • letconst是可以被块级作用域显示使用范围,任何一个可以书写代码的{}就是块级作用域,由let/const定义变量的{}称为暂时性死区
     if(true){
         var n = 200;
         // 在大括号中 let/const声明的变量,会被大括号限制使用范围
         let user = 'zs';
         const age = 20;
         if(true){
           console.log( user ) //'zs'
           console.log( age ) // 20
         }
       }
     console.log( n )  // 200
     // console.log( user ) // 报错 user is not defined
     // console.log( age ) // 报错 age is not defined
    

(4)letconst的区别

  • ①定义时的赋值

    • let定义变量时,可以不赋值
    • const定义变量时,必须赋值
     let n;
     const m; // 报错 没有赋值
    
  • ②值修改

    • let定义的变量值可以修改
    • const定义的变量不可修改
     let n = 6;
     n = 8;
     console.log( n ) // 8
       
     const m = 8;
     // m = 9; // 报错
     console.log( m )
     ​
     const obj = {name:'zs'};
     // obj 中存储的是对象的地址
     obj.name = 'lisi'; // 并没有修改o中存储的地址
     console.log( o ) // {name: "lisi"}
    

二、箭头函数

  • ES6中定义函数的一种方式,只能用来定义匿名函数表达式(匿名函数)

    • var fn = function(){}var obj = { f:function(){} }setInterval(function(){},1000)事件源.on事件类型 = function(){}
  • 语法:()=>{}()书写形参的位置,=>箭头函数的标志,{}函数的函数体

     // 函数表达式
     let fn = function(){console.log( '666' )}
     fn();
     ​
     // 箭头函数
     let ff = ()=>{console.log( '888' )}
     ff()
    
  • 特点:

    • ①可以省略小括号不写

      • 当函数只有一个形参时,可以不写;如果没有形参或两个以上形参则必须写小括号
       let ff = n => {console.log( n )}
       ff(666)  // 666
       ​
       // 不能省略的情况
       let f = (n,m)=>{console.log( n,m )}  
       f(10,20)  // 10 20
      
    • ②可以省略大括号不写

      • 当函数内代码只有一句话(一个表达式)时,可以省略,并且会自动返回这一句的结果,自动把这句代码的结果当做函数的返回值
       let ff = n => console.log(n);
       ff(100)  // 100
       ​
       let fn = n => {return n+100};
       // let fn = n=> n+100;
       let res = fn(100);
       console.log( res )  // 200
      
    • ③箭头函数没有 arguments

       let fn = function () {
           console.log( arguments )
       }
       fn(10,20,30)
       ​
       let fn = ()=> { console.log( arguments ) } 
       // 报错 arguments is not defined
       fn(10,20,30)
      
    • ④没有this

      • 官方:箭头函数内的this就是上下文的this
      • 私人:箭头函数内的this就是定义箭头函数外部作用域的this
      • 箭头函数内的this和调用箭头函数的方式没有关系,和调用箭头函数的位置有关系
       document.onclick = function () {
           console.log( this ) // this就是事件源
       }
       console.log(this); // window
         
       document.onclick = () => {
           // 箭头函数定义在全局作用域中
           // 则箭头函数内 的this指向全局作用域中的this window
           console.log(this)  // window
       }
        
       document.onclick = function () {
           console.log(this) // this就是事件源 document
           let obj = {
             fn: function () {
               console.log(this)
            },
            ff: () => {
               // 箭头函数定义在事件处理函数中
               // this指向事件处理函数中的this 事件源 document
               console.log(this)
             }
           }
           obj.fn()  // this指向调用fn方法的对象
           obj.ff()  // this指向事件处理函数中的this 事件源 document
       }
      

三、函数形参默认值

  • 在函数定义的小括号中,直接给形参赋值,这个值就是函数内形参使用的默认值
  • 注意: 箭头函数中如果形参使用了默认值,则不能省略小括号
 let ff = function (n1=10,n2=20) {
     console.log( n1,n2 )
 }
 // ff();// 形参使用默认值  n1为10  n为20
 // ff(66);// 形参n1使用实参传递的66 形参n2使用默认值  n1为66  n2为20
 ff(66,88);// 形参n1使用实参传递的66 形参n2使用实参传递的88  n1为66  n2为88

四、模板字符串

  • 使用反括号包裹 ``
  • ①在模板字符串中可以换行书写
  • ②在模板字符串中可以解析变量,${变量},在${}中可以执行一些简单的代码
 let str = 
     `<ul>
       <li>${username}</li>
       <li>${age+1}</li>
       <li>${gender}</li>
     </ul>
     `;
 console.log(str)
 document.body.innerHTML = str;

五、对象简写

  • ①如果对象的属性名和属性值的变量名一样,可以简写,将属性名、冒号省略
  • ②如果对象中属性对应的值只有一个匿名函数,可以简写,将冒号、function省略
 let username = '张三'
 let userage = 18;
 // 对象
 let obj = {
     // username: username,
     username,
     userage,
     // fn:function(){console.log( 666 )},
     fn(){console.log( 666 )}
   }
   console.log( obj )
   obj.fn()

六、解构赋值

  • 作用:快速的获取数据结构中的某一个值

(1)解构数组

  • 语法:解构 = 数组
  • 数组解构使用[][]在赋值等号的左边叫解构[]在赋值等号的右边叫数组
 // let n1;
 // let n2;
 // let n3;
 // let n4;
 [n1, n2, n3, n4, n5] = ['a', 'b', 'c', 'd'];
 console.log(n1, n2, n3, n4) // a b c d
 console.log( n5 )// undefined

(2)解构对象

  • 语法:解构 = 对象
  • 解构对象使用{}{}在赋值等号的左边叫解构{}在赋值等号的右边叫数组
  • 在左边的 {} 中 你需要书写解构的key(属性名)
 let obj = { username: 'liam', age: 18 };
 let { username, age } = obj// 等价于 let username = obj.username, age = obj.age
 console.log(username, age)  //  liam 18
 let { age:userage} = obj // 等价于 let userage = obj.age
 console.log( userage ) // 18
 let o = {
     name: 'zs',
     age: 20,
     info: {
       height: 180,
       weight: 180,
       addr: {
         city: '北京'
       }
     }
 }
 ​
 let { name: username, age, info: { height, weight, addr: { city } } } = o;
 console.log(username, age, height, weight, city);  // zs 20 180 180 北京

七、运算符

(1)展开运算符...

  • 可以展开数组和对象,展开的对象需要放在{},展开的数组需要放在[]或方法函数实参位置
 let arr = [1,2,3,4,5,'a','b','c'];
 console.log(...arr ) // 1 2 3 4 5 "a" "b" "c"

(2)合并运算符...

  • ...既可以展开数组,也可以合并多个数据,得到数组
  • ...用于函数形参位置时,就是一个合并运算符,可以把多个实参合并起来得到一个数组
 // 合并数组使用
 let arr1 = [1, 2, 3, 4];
 let arr2 = [5, 6, 7, 8];
 var newArr = [...arr1,...arr2]
 console.log( newArr )// [1, 2, 3, 4, 5, 6, 7, 8]
 ​
 // 合并对象使用
 let o = { name: 'liam', age: 18 };
 let obj = {
     gender:'男',
     ...o
 }
 console.log( obj ) // name:'liam',age:18,gender:'男'
 let fn = function (...arr) {
     console.log( arr ) // [1, 2, 3, 4, 5, 6]
 }
 fn(1, 2, 3, 4, 5, 6);
 ​
 // 合并运算符,可以适当的弥补箭头函数内没有argumenst的缺陷
 let ff1 = (...ars) => {
     console.log( ars ) // [1, 2, 32, 34, 4]
 }
 ff1(1, 2, 32, 34, 4)
 ​
 let ff2 = (n1, n2, n3, ...ars) => {
     console.log( n1,n2,n3 ) // 1 2 3
     console.log(ars) //  [4, 5, 6, 7]
 }
 ff2(1, 2, 3, 4, 5, 6, 7)

八、模块化开发

九、万能检测数据类型

  • 语法:Object.prototype.toString.call(你要检测的数据)
  • 返回值:[object 数据类型]
 console.log(Object.prototype.toString.call(1))  // [object N]

十、JSON 方法

  • json 是一种特殊的字符串个是,本质是一个字符串

     var jsonObj = '{ "name": "Jack", "age": 18, "gender": "男" }'
     var jsonArr = '[{ "name": "Jack", "age": 18, "gender": "男" }, { "name": "Jack", "age": 18, "gender": "男" }, { "name": "Jack", "age": 18, "gender": "男" }]'
    
  • 就是对象内部的 keyvalue 都用双引号包裹的字符串(必须是双引号)

  • 我们有两个方法可以使用 JSON.parseJSON.stringify
  • json.stringify 是将 js 的对象或者数组转换成为 json 格式的字符串

(1)JSON.parse

  • JSON.parse 是将 json 格式的字符串转换为 js 的对象或者数组

     var jsonObj = '{ "name": "Jack", "age": 18, "gender": "男" }'
     var jsonArr = '[{ "name": "Jack", "age": 18, "gender": "男" }, { "name": "Jack", "age": 18, "gender": "男" }, { "name": "Jack", "age": 18, "gender": "男" }]'
     ​
     var obj = JSON.parse(jsonObj)
     var arr = JSON.parse(jsonArr)
     ​
     console.log(obj)
     console.log(arr)
    
    • obj 就是我们 js 的对象
    • arr 就是我们 js 的数组

(2)JSON.stringify

  • JSON.stringify 是将对象或者数组转换为 json 格式的字符串

     var obj = {
       name: 'Jack',
       age: 18,
       gender: '男'
     }
     var arr = [
       {
         name: 'Jack',
         age: 18,
         gender: '男'
       },
       {
         name: 'Jack',
         age: 18,
         gender: '男'
       },
       {
         name: 'Jack',
         age: 18,
         gender: '男'
       }
     ]
     ​
     var jsonObj = JSON.stringify(obj)
     var jsonArr = JSON.stringify(arr)
     ​
     console.log(jsonObj)
     console.log(jsonArr)
    
    • jsonObj 就是 json 格式的对象字符串
    • jsonArr 就是 json 格式的数组字符串

十一、this 关键字

  • 每一个函数内部都有一个关键字是 this

  • 可以让我们直接使用的

  • 重点: 函数内部的 this 只和函数的调用方式有关系,和函数的定义方式没有关系

  • 函数内部的 this 指向谁,取决于函数的调用方式

    • 全局定义的函数直接调用,this => window

       function fn() {
         console.log(this)
       }
       fn()
       // 此时 this 指向 window
      
    • 对象内部的方法调用,this => 调用者

       var obj = {
         fn: function () {
           console.log(this)
         }
       }
       obj.fn()
       // 此时 this 指向 obj
      
    • 定时器的处理函数,this => window

       setTimeout(function () {
         console.log(this)
       }, 0)
       // 此时定时器处理函数里面的 this 指向 window
      
    • 事件处理函数,this => 事件源

       div.onclick = function () {
         console.log(this)
       }
       // 当你点击 div 的时候,this 指向 div
      
    • 自调用函数,this => window

       (function () {
         console.log(this)
       })()
       // 此时 this 指向 window
      

强行改变 this 指向的三个方法

  • 刚才我们说过的都是函数的基本调用方式里面的 this 指向
  • 我们还有三个可以忽略函数本身的 this 指向转而指向别的地方
  • 这三个方法就是 call / apply / bind
  • 是强行改变 this 指向的方法

call

  • call 方法是附加在函数调用后面使用,可以忽略函数本身的 this 指向

  • 语法: 函数名.call(要改变的 this 指向,要给函数传递的参数1,要给函数传递的参数2, ...)

     var obj = { name: 'Jack' }
     function fn(a, b) {
       console.log(this)
       console.log(a)
       console.log(b)
     }
     fn(1, 2)
     fn.call(obj, 1, 2)
    
    • fn() 的时候,函数内部的 this 指向 window

    • fn.call(obj, 1, 2) 的时候,函数内部的 this 就指向了 obj 这个对象

    • 使用 call 方法的时候

      • 会立即执行函数
      • 第一个参数是你要改变的函数内部的 this 指向
      • 第二个参数开始,依次是向函数传递参数

apply

  • apply 方法是附加在函数调用后面使用,可以忽略函数本身的 this 指向

  • 语法: 函数名.apply(要改变的 this 指向,[要给函数传递的参数1, 要给函数传递的参数2, ...])

     var obj = { name: 'Jack' }
     function fn(a, b) {
       console.log(this)
       console.log(a)
       console.log(b)
     }
     fn(1, 2)
     fn.call(obj, [1, 2])
    
    • fn() 的时候,函数内部的 this 指向 window

    • fn.apply(obj, [1, 2]) 的时候,函数内部的 this 就指向了 obj 这个对象

    • 使用 apply 方法的时候

      • 会立即执行函数
      • 第一个参数是你要改变的函数内部的 this 指向
      • 第二个参数是一个 数组,数组里面的每一项依次是向函数传递的参数

bind

  • bind 方法是附加在函数调用后面使用,可以忽略函数本身的 this 指向

  • 和 call / apply 有一些不一样,就是不会立即执行函数,而是返回一个已经改变了 this 指向的函数

  • 语法: var newFn = 函数名.bind(要改变的 this 指向); newFn(传递参数)

     var obj = { name: 'Jack' }
     function fn(a, b) {
       console.log(this)
       console.log(a)
       console.log(b)
     }
     fn(1, 2)
     var newFn = fn.bind(obj)
     newFn(1, 2)
    
    • bind 调用的时候,不会执行 fn 这个函数,而是返回一个新的函数
    • 这个新的函数就是一个改变了 this 指向以后的 fn 函数
    • fn(1, 2) 的时候 this 指向 window
    • newFn(1, 2) 的时候执行的是一个和 fn 一摸一样的函数,只不过里面的 this 指向改成了 obj