zoukankan      html  css  js  c++  java
  • ES6系列---【ES6新语法】

    1、ES6与JavaScript的区别

    ​ ES6仅仅是一种语法规范。JavaScript只是ES6的一种实现,具体实现到多少看浏览器厂家执行规范的程度。javascirpt 还包括DOM、BOM,另外JavaScript还可以应用与后台开发环境例如node。

    2、let 与 const

    ES6新增用于声明变量的语法。

    2.1 let与var的区别

    a) var 是函数作用域,let是块作用域

    • let与var 用法是一样的

    • let在 if、for循环等语句中声明的变量也是局部变量

    • 优点:et声明的变量可以防止全局污染。容易产生bug

    b) var 有变量提升,let不存在变量提升

    • let变量声明必须先声明,再使用,否则报错;

    • 优点:对于开发者来说,代码更严谨,报错更加一目了然,容易排除。

    c) var 可以重复声明的,let在同一作用域下不能重复声明

    • 函数的形参let 也不允许重复声明。

    • 优点:在复杂的项目开发中,程序员重复声明变量在所难免,var的情况不报错,不易觉察,容易产生bug。let直接报错,比较直观容易排除

    2.2 let变量在for循环中的应用

    ​ let变量在for循环中,分为父作用域和子作用域。for循环的圆括号中的变量是父作用域中,for循环的大括号实际为子作用域。

      var btns = document.getElementsByTagName("button");
        for (let i = 0; i < btns.length; i++) {
          btns[i].onclick = function () {
            alert(i + 1);
          }
        }
    

    3、const 常量

    const常量用于项目中不经常会改变的内容。例如:地址,数据库账号,密码、圆周率PI

    • const特征:

    • 一旦被声明并赋值后不可再改动

    • 声明和赋值必须同时进行

    • 其他特征和let一样

    • 约定俗称:常量名称大写

    • 特殊说明:

      const常量对于复杂类型来说,只能保证保存地址的不能被更改,至于地址指向的内容是可以修改的。

    4、et变量与顶级对象(window)解绑

    • var 声明的全局变量,实际上是window对象的属性,这是JavaScript遗留的设计败笔
    • 从ES6开始,let 声明的变量与window对象不再绑定
     let a = "ok";
     console.log( window.a ); //undefined
    

    4、解构赋值

    ​ 解构赋值: ES6按照一定的模式,将结构化的数据(数组、对象)中的数据提取出来,赋值给变量

    • 总结特征:

      • 必须有赋值运算符(等号)
      • 等号的前面是模式和变量
      • 等号的后面是数组或对象
    • 数组解构赋值的几种情况

    • 要解构的数据和变量一一对应

    • 要解构的数据比变量多,没有影响

    • 要解构的数据比变量少,解构失败变量的值为undefined

    • 解构赋值允许使用 空的逗号实现缺省

    • 解构赋值的默认值(当解构赋值失败时或者严格等于undefined时默认值生效)

    let [x=1,y=x] = []; // x=1 y=1
    let [x=1,y=x] = [2]; //x=2, y=2
    let [x=1,y=x] = [1,2]; //x=1 y=2
    let [x=y,y=1] = []; //报错,变量y未声明即使用了
    
    • 对象解构赋值的情况

    • 对象的解构赋值,因为对象中的属性没有次序,因此对象必须依靠键的匹配实现解构赋值。

    • 对象解构赋值的默认值(当解构赋值失败时或者严格等于undefined时默认值生效)

    // let {name:xxx,sex:yyy,age:zzz} = {name:"张三",age:20,sex:"男"}
      // console.log( xxx, yyy,zzz);
      // 实际可能写为:
      // let {name:name,sex:sex,age:age} = {name:"张三",age:20,sex:"男"}
      // console.log( name,sex,age);
      // ES6允许简化为:
      let {name,sex,age} = {name:"张三",age:20,sex:"男"}
      console.log( name,sex,age);
    
    • 函数形参的解构赋值

      • 可利用数组实现解构赋值。注意声明函数时的形参此时不是数组,是模式和变量
       function fn([a,b,c]){
          console.log( a+b+c );
        }
        fn([2,3,4]); */
        // 相当于
        // let [a,b,c] =  [2,3,4]   
      
      • 利用对象实现函数解构赋值。注意,声明函数时的形参不是对象,是模式和变量
      function demo({x,y}){
          return x*y
        }
        console.log( demo({x:2,y:2}) ); */
        // 相当于
        // let {x,y} = {x:2,y:2}
      
      • 函数形参解构赋值时的默认值
      function fn({x=0,y=0}){
          return x*y
        } */
        // console.log( fn({x:1}) )
      

    5、解构赋值应用场景

    1) 交换变量的值

    2) 获取函数的多个返回值

    3)利用解构赋值实现ajax封装函数

      // 利用解构赋值实现ajax封装函数。可灵活使用解构赋值的默认值,这样调用函数时只需要传递必要的参数即可
      function sendAjax({type="get",url,data=null,dataType="json",timeout="5000"}) {
        $.ajax({
          type: type, //请求的方法 get post
          url: url,  //请求的地址
          data: data, // 请求时发送的数据
          dataType: dataType, //期望返回的数据类型
          // ajax成功后的回调函数
          success: function (response) {
            console.log(respnse);
          },
          // 失败时的回调函数
          error: function (err) {
            console.log(err);
          }
        });
      }
      // 函数调用时传递实参为一个对象
      sendAjax({url:"http://baidu.com/01.json"});
      sendAjax({url:"http://baidu.com/02.json"});
    

    以上代码进一步优化为:

    将封装函数保存为外部js, 需要时引用:

      // 利用解构赋值实现ajax封装函数。可灵活使用解构赋值的默认值,这样调用函数时只需要传递必要的参数即可
      function sendAjax({type="get",url,data=null,dataType="json",timeOut="5000"},callback) {
        $.ajax({
          type: type, //请求的方法 get post
          url: url,  //请求的地址
          data: data, // 请求时发送的数据
          dataType: dataType, //期望返回的数据类型
          // ajax成功后的回调函数
          success: function (response) {
            // console.log(respnse);
            callback(response)
          },
          // 失败时的回调函数
          error: function (err) {
            console.log(err);
          }
        });
      }
    
    <script src="./sendAjax.js"></script>
    <script>
    sendAjax({type:"post",url:"http://api.shenzhou888.com.cn/v2/ecapi.banner.list"},function(data){
        // 渲染页面代码
        console.log( data );
      });
    </script>
    

    6、字符串扩展--模板字符串

    ​ ES6可以使用模板字符串(``) 代替原来的繁琐的拼字符串渲染页面的方式。可以使用 ${ } 来嵌套变量或js表达式。

      let str = `<ul>
          <li><span class="name">姓名:</span><span class="uname">${student.name}</span></li>
          <ul>
            <li>${ "语文:"+ student.score[0]}</li>
            <li>${ "数学:"+ student.score[1]}</li>
            <li>${ student.score[2]}</li>
          </ul>
          <li>性别:${ student.sex }</li>
        </ul>`;
    
        let box = document.getElementById("box");
        box.innerHTML = str;
    

    7、ES6对象扩展

    • 允许属性名简写
      let name = "jack";
      let sex = "男"
      let obj = {
        name,
        sex,
        say(){
          console.log( name );
        }
      }
    
    
    • ES6支持对象的键为表达式
    let city = {};
      for(let i=0;i<26;i++){
        console.log( String.fromCharCode(i+65) );
        let key = String.fromCharCode(i+65);
        city[key] = [];
      }
    
    • 几个静态方法
      • Object.assign() 对象的合并
      • Object.keys() 获取对象上所有的键,以数组的形式返回
      • Object.values() 获取对象上所有的值,以数组的形式返回
      // 对象的合并,第一个参数为合并的目标对象
      let obj1 ={ name:"jack"};
      let obj2 = { sex:"男"};
      Object.assign(obj1, obj2);
    
      console.log( obj1 );
    

    8、数组扩展

    • Array.from() 将类数组对象转换为真正的数组
      // nodelist, htmlCollection, argument 类数组对象
    // 典型的类数组对象的形式:
      let obj = {
        "0":"hello",
        "1":"world",
        "length":2
      }
      console.log( obj );
      console.log( Array.from(obj) );
    
    
    • includes()

    ​ 用来查找数组中是否存在指定的值,有就返回true, 没有返回false。与indexOf的功能类似。

      // includes() 用来查找数组中是否存在指定的值,有就返回true, 没有返回false。解决了indexOf()对NaN无效的bug
      let arr = [2,3,4,5,NaN];
    /*   if( arr.indexOf(NaN) != -1 ){
        console.log("找到了");
      }else{
        console.log("没找到");
      } */
      if( arr.includes(NaN) ){
        console.log("找到了");
      }else{
        console.log("没找到");
      }
    

    9、函数扩展

    ES6可以使用箭头(=>)来简化函数的声明。

    • 特征: 用 => 替换了 function

    • =>的后面:

      • 如果函数体内只有一行代码,大括号可省略
      • 如果只有一行代码而且是return语句,return 也可省略
      • 如果只有一行代码而且是retrun一个对象,为了避免歧义,要使用圆括号包起来
    • =>的前面:

      • 如果只有一个形参,圆括号也可以省略
      • 如果有多个或者没有形参,圆括号不能省略
    • 箭头函数中的this指向规律

    • ES6之前的普通函数中this指向规律:

      1)在全局函数或定时器的回调函数中this指向 window

      2)在事件处理函数中this指向事件源

      3)在对象的方法中this指向对象本身

      4)可使用call/apply/bind 改变this指向

    • ES6中箭头函数的this指向规律:

      1)定义好箭头函数后,this的指向就确定了,与call/apply等没有关系

      2)永远指向其上层环境(环境指的的是函数内或全局下,只有这两种情况,其他的大括号不能称为环境)

      function Person(){
        let fn1 = ()=>{
          console.log( this );
        }
        fn1();
      }
    // 1、Person当普通函数调用时
      // Person();
    // 2、Person当构造函数使用时,构造函数中的this发生了改变,指向创建的新对象。那么箭头函数中的this也指向新创建的对象。
      new Person();
    
    • 箭头函数的不适应用的情况:

    ​ 1)事件处理函数中;

    ​ 2)对象的方法中;

    ​ 3)构造函数中

    函数形参的默认值

      // 函数形参的默认值
      function fn(name="杨营"){
        // if(!name){
        //   name = "杨营";
        // }
        // name = name || "杨颖";  //短路语法
        console.log(`我是:${name}` );
      }
      fn("刘子琪")
    

    rest剩余参数运算符 和 spread 扩展运算符

    rest 剩余参数,用于获取多余(全部)的实参并放入一个数组中。

      // rest剩余参数运算符(...),只出现在函数形参声明处,作用可代替arguments,实现将实参转换为数组
      function fn(...c){
        console.log( Array.from(arguments)  );
        console.log( c );
      }
      fn(1,2,3,4,5,6)
    

    spread扩展运算符(...),作用是将结构化的参数(数组,对象)转换为逗号分隔的参数序列。类似rest的逆运算。

    /*   let arr = [2,3,4,5]
      console.log( ...arr );
     */
      // 应用场景1 -- 函数传参
    /*   let arr = [2,5,0,9];
      console.log( Math.min(...arr) );  */
      // 应用场景2--数组合并
      let arr1 = [2,3,4,5];
      let arr2 = ["hello","ok"];
      let arr3 = [...arr1,...arr2];
      // 对象合并
      let obj1 = {
        name:"jack"
      }
      let obj2 = {
        age:20
      }
      let obj3 = {
        ...obj1,
        ...obj2
      }
      console.log( obj3 );
    

    10、symbol 类型

    ​ symbol是ES6新增的数据类型,string、number、boolean、null、undefined、object、symbol。

      // symbol类型,作用是产生一个永不和其他symbol相同的独一无二的值。
      // 创建symbol时可添加一个参数,起到在控制台输出时的区分作用,类似于程序中的注释,对程序的执行没有任何影响
      let s1 = Symbol("老大");
      let s2 = Symbol("老二");
      console.log(typeof s1); 
      console.log( s1 == s2 ); //永远false
      console.log(s1,s2);
    

    11、set数据类型

    ​ set 是ES6新增的类似数组的数据结构。特点:set中的成员永远是唯一,允许重复。set的主要作用是过滤数组中重复的项。

      // set 数据类型,类似数组的数据结构,作用:可以过滤到数组中重复的项
      let arr = [2,3,2,4,3,0,1,4];
      let s1 = new Set(arr);
      console.log( s1 );
      console.log( Array.from(s1) );
    

    set 自有的属性和方法:

    size set中成员的个数

    add() 添加某个值

    delete() 删除某个值

    has() 返回一个布尔值,表明是否包含有某个值

    clear() 清除set中所有成员

    12、Map数据类型

    ​ Map是ES6新增的类似对象的数据结构,也是键值对的集合。

    • 特点:键的范围不限于字符串,可以是各种类型的值都可以当做键,比object提供的‘字符串一值’的对应更加完善

    • set 自有的属性和方法:

      • size 类似数组的length属性:size用于返回Map集合的内容长度
      • set(key,value):添加一个键值数据
      • get(key):根据key获取value
      • has(key):返回布尔值,表明是否包含有某个值
      • delete(key):根据指定的key删除数据
      • clear():清除Map中所有成员,没有返回值
      //Map基本使用
      let m = new Map();
      m.set('c', 'content')
      m.get('c')//content
      m.size//1
      m.has('c') // true
      m.delete('c')
      m.has('c')
      m.clear()
      
      //Map结构和数组结构之间的转换
      let map = new Map([
        [1, 'one'],
        [2, 'two'],
        [3, 'three'],
      ]);
      [...map.keys()]// [1, 2, 3]
      [...map.values()]// ['one', 'two', 'three']
      [...map.entries()]// [[1,'one'], [2, 'two'], [3, 'three']]
      [...map]// [[1,'one'], [2, 'two'], [3, 'three']]
      
    • Map 循环遍历

      Map 原生提供三个遍历器:

      • keys():返回键名的遍历器。
      • values():返回键值的遍历器。
      • entries():返回所有成员的遍历器
    let map = new Map([
      ['F', 'no'],
      ['T',  'yes'],
    ]);
    for (let key of map.keys()) {
      console.log(key);
    }
    // "F"
    // "T"
    for (let value of map.values()) {
      console.log(value);
    }
    // "no"
    // "yes"
    for (let item of map.entries()) {
      console.log(item[0], item[1]);
    }
    // "F" "no"
    // "T" "yes"
    // 或者
    for (let [key, value] of map.entries()) {
      console.log(key, value);
    }
    // 等同于使用map.entries()
    for (let [key, value] of map) {
      console.log(key, value);
    }
    上面代码最后的那个例子,表示 Map 结构的默认遍历器接口(Symbol.iterator 属性),就是 entries 方法。
    map[Symbol.iterator] === map.entries // true
    

  • 相关阅读:
    WEBAPP开发技巧
    手机中的javascript事件
    I6下实现FIXED
    vim 使用帮助
    javascript小技巧
    webkitbox & translate CSS3动画详解
    backbone中的实例中文注释
    getClientRect和getBoundingClientRect获取节点的屏幕距离
    javascript判定不同浏览器
    jQuery中的trigger(type, [data]) 原生实现方法
  • 原文地址:https://www.cnblogs.com/chenhaiyun/p/14654917.html
Copyright © 2011-2022 走看看