ES6

作者: 黑色的五叶草 | 来源:发表于2018-12-26 11:22 被阅读0次

    基础部分:

    一、新的声明方法

    支持块作用域

    {
      let a = 1;
    }
    console.log(a)  //undefined
    

    let:不可重复声明、支持块级作用域,可先声明后赋值
    const:常量,声明时就要赋值

    <button></button>
    <button></button>
    <button></button>
    
    <p></p>
    <p></p>
    <p></p>
    
    <script>
        var buttons = document.querySelectorAll('button');
        for (let i = 0; i < buttons.length; i++) {
            buttons[i].onclick = function () {
                for (let i = 0; i < buttons.length; i++) {
                    // 外层点击时清除所有button的样式
                    buttons[i].className = '';
                    ps[i].className = ''
                }
                // 对点击的添加样式
                this.className = 'active';
                ps[i].className = 'active';
            }
        }
    </script>
    

    二、解构赋值:

    1.两边的结构必须一样
    2.赋值和解构同时完成

    let [a,b]=[5,8];
    let {a,b}={12,5};

    • 数组解构,空位可以用占位符
      let arr = [1, 2, 3];
      let [a ,b] = arr;
      console.log(a, b);  // 1 2
      
      // 对空位占位
      let [x, , z] = arr;
      console.log(x,z);   // 1 3
      
    • 对象解构,左右变量名必须对应
      // 1.从对象中结构出left变量
      let {forward, back} = {forward: 100, back: 200};
      console.log(forward);   //100
      
      // 2.从对象中解构出left值,并赋给L变量 -> 避免覆盖Window下全局变量
      let {left: L, right: M} = {left: 100, right: 200};
      console.log(L);     //100
      
      // 3.多重解构
      let {foo: [a, b]} = {foo: [10, 20], bar: 'bar'};
      console.log(a, b);  // 10 20
      
    • 字符串解构
      // 对字符串解构,会产生一个特殊的行为
      let [c, d, e, f, g, h] = 'string';
      console.log(c, d, e, f, g, h);    // s t r i n g
      

    三、块级作用域

    是什么:相当于添加了一个语法块

    {
    }
    

    替代闭包:let const关键字形成块级作用域替代匿名函数创建闭包

    let aBtn=document.getElementsByTagName('input');
    
    for(let i=0;i<aBtn.length;i++){
      aBtn[i].onclick=function (){
        alert(i);
      };
    

    四、函数:箭头函数和this

    箭头函数形式
    1.如果有且仅有一个参数,()也可以不写
    2.如果有且仅有一个语句并且是return,{}也可以不写

    1. (n) => { return n+1 }
    2. n => n+1
    let arr=[12,8,37,26,9];
    
    /*arr.sort(function (n1, n2){
      return n1-n2;
    });*/
    arr.sort((n1, n2)=>n1-n2);
    

    箭头函数的this始终指向原创建对象或函数

    /*
    let json = {
      a: 12,
    
      //this=>当前的环境
      fn: function () {
        alert(this.a);
      }
    }
    json.fn();
    */
    
    class Json {
      constructor() {
        console.log(this);
    
        this.a = 12;
        this.fn = () => {
          console.log(this);
          alert(this.a);
        }
      }
    }
    let json = new Json();
    
    
    let oDate = new Date();
    oDate.fn = json.fn;
    
    oDate.fn();
    
    this始终指向Json对象

    五、扩展运算符 ...

    参数展开、数组展开、对象展开

    1. 参数展开

        function show(a, b, ...c){
          console.log(a, b, c);
        }
    
        show(12,5,4,8,19,27,36);
    
        // 12 5 [4,8,19,27,36]
    

    2. 数组展开

    let arr1=[12,5,8];
    
    function show(a,b,c){
      alert(a+b+c);
    }
    
    show(...arr1);    // 25
    

    3. 对象展开

    let json={a: 12, b: 5, c: 99};
    
    let json2={
      ...json,
      d: 999
    };
    
    console.log(json2);
    

    4.数组合并

    let arr1 = [1, 2, 3];
    let arr2 = ['a', 'b'];
    
    let arr3 = [...arr1, ...arr2];
    console.log(arr3);    // [1, 2, 3, "a", "b"]
    

    六、原生对象扩展

    • Array扩展:
      map: 映射,一一对应。[68, 30, 60, 77, 22] -> [及格,不及格,及格,及格,不及格]
      reduce: 缩减(求和、平均) n>1
      filter: 过滤
      forEach: 遍历
    • 模板字符串:识别换行符与变量表达式解析${表达式}
    • JSON写法:JSON.parse()转换成JSON, JSON.stringify()转换成对象
    • 对象扩展:对象的属性名必须是字符串
      var x = 'souse';
      var obj = {
          // 属性名表达式
          [x]: 1
      }
      console.log(obj);   // {souse: 1}
    

    七、异步(详见笔记)

    promise
    async/await

    八、面向对象:主要特征在于封装

    ES5面向对象:

    • 没有语言自身的统一的写法
    • 以函数的形式去写对象(不区分类与构造函数)

    ES6面向对象:

    • class 类声明
    • constructor 构造函数
    • extends 继承
    • super 父类/超类

    面向对象:

    // 声明类
    class Person{
      // 声明构造函数
      constructor(name, age){
        this.name=name;
        this.age=age;
      }
    
      showName(){
        alert(this.name);
      }
      showAge(){
        alert(this.age);
      }
    }
    
    let p = new Person('blue', 18);
    p.showName();
    p.showAge();
    

    继承:

    /**
     * 继承
     * 1.声明子类
     * 2.extends 声明继承父类
     * 3.super 取得父类属性
     */
    class Worker extends Person {
        constructor (name, age, job) {
            // 取得父类的属性
            super(name, job);
    
            // 声明子类自身的属性
            this.job = job;
        }
    
        // 声明子类自身的方法
        showJob () {
            alert(this.job);
        }
    }
    
    let w = new Worker('blue', '18', '爱吹逼的小福将');
    w.showName();
    w.showAge();
    w.showJob();
    

    九、ES6模块

    1. 导出(export)
    • 变量
    export let a=12;
    export const a=12;
    
    • 一堆
    let a,b,c=...;
    export {a, b, c, ...};
    
    • 导出函数
    export function show(){
      ...
    }
    
    • 导出class
    export class Person{
    ...
    }
    

    默认成员

    export default
    
    1. 导入
    • 引入所有成员
    import * as mod1 from 'xxx'; 
    
    • 引入default成员
      import mod1 from 'xxx'; 对应 export default
      部分引入
      import {a,b as name2} from 'xxx'; 对应export {a, b, c, ...};
    • 只引入样式表
    import 'xxx';
    
    • 异步引入 import() 函数本身是一个 promise 异步操作,要用到await
    let p =  import("./mod1");
    ^
    |
    let p = await import("./mod1");
    

    进阶部分:

    一、Symbol的使用:

    属性私有化(数据保护):每次创建的Symbol('a')都是一个新的实例

    如下例所示,希望_gender属性只读不可写。传入的第二个gender参数,只可以通过调用原型对象的方法查看

    var Person = (function() {
        // 声明一个私有变量
        var _gender = '';
        // 调用私有变量形成闭包
        function P(name, gender) {
            this.name = name;
            //this.gender = gender;
    
            _gender = gender;
    
        }
        P.prototype.getGender = function() {
            return _gender;
        }
    
        return P;
    })();
    
    var p1 = new Person('莫涛', '男');
    console.log(p1);
    console.log(p1.getGender());
    

    二、迭代(循环)

    迭代语句循环迭代对象,具有迭代器的迭代对象能被循环,迭代协议规定了迭代器

    1. 迭代协议:规定了迭代与实现的逻辑
    2. 迭代器[Symbol.iterator]:本质是一个方法,具体迭代的实现逻辑。数组和类数组对象都有,对象没有
    3. 迭代对象:可迭代的对象——具有[Symbol.iterator]方法
    4. 迭代语句:
      for...in 以原始插入的顺序迭代对象的可枚举属性
      for...of 根据迭代对象的迭代器具体实现迭代对象数据
      for of内部实现原理:1.首先添加迭代器方法,迭代器定一个a(value)变量并返回出一个对象,2.对象内部每次循环next方法,next方法返回出一个对象,如果不满足条件(done: false)就继续循环,直到done:true停止循环,3.外部每次循环的变量attr即迭代器内部的value变量。
      for of迭代过程:1.循环前先判断是否有symbol.iterator方法 2.有迭代器方法后继续执行next函数,next函数会被多次执行 3.直到next函数内部的done属性为true时停止循环


      for...of方法的实现,迭代value
    var obj = {
      left: 100,
      top: 200
    }
    obj[Symbol.iterator] = function() {
      let keys = Object.keys(obj);  //['left', 'top']
      let len = keys.length;  //迭代的次数
      let n = 0; //当前迭代第几次
    
      return {
        next: function () {
          if (n < len> {
            return {
              // [n++]  先赋值[n],再++
              // value: keys[n++],
              value: obj[keys[n++]];  //迭代的返回值
              // value {key: keys[n], value: obj[keys[n++]]},
              done: false
            } else {
              return {
                done: true
              }
            }
        }
    }
    for (var attr of obj) {
      console.log(attr);
    }    
    // left top
    // 100 200
    

    三、冻结对象

    const arr = [1, 2 ,3];
    
    1. const 声明的变量不可修改,但是数组可以通过push的方式推入新值
    arr.push(4);
    
    console.log(arr)  // [1, 2, 3, 4];
    
    1. 使用冻结对象禁止数组扩展
    const arr = Object.freeze([1, 2, 3]);
    
    arr.push(4);
    
    console.log(arr)  // 报错,提示对象不可扩展
    

    相关文章

      网友评论

          本文标题:ES6

          本文链接:https://www.haomeiwen.com/subject/pdaclqtx.html