课后作业——ES6规范

306 阅读3分钟

ECMA前身今世

Ecma International —— 瑞士标准协会, 负责制定国际标准

JavaScript —— 经由Netscape 和 Sun Microsystems创建并提交国际标准,取名ECMAScript

name - ES6 === official name -ES2015

常量

const 常量标识

    const LIMIT = 10;
    const OBJ_MAP = {
        a:'A',
        A:'a'
    };
    const QUEUE = [1, 2, 3, 4, 5];

1.不允许重复声明赋值

    // 变量重新赋值
    var arg1 = '1';
    arg1 = '2';
    
    // 常量
    // ES5
    Object.defineProperty(window, 'arg2',{
        value:'1',
        writable: false   //不允许修改
    })
    //arg2不能被改变
    
    // ES6
    const arg3 = '1';
    //arg3不能被改变
    
    //const 不允许重复声明
    const arg4='1'
    const arg4='1' // 再次声明会报错

2. 块级作用域

    if(true){
        var arg1 = '1';
    }
    console.log('arg1',arg1); //arg1 1
    
    if(true){
         const arg2 = '2';
     }
     console.log('arg2',arg2); //undefined

3. 无变量提升

    console.log(arg1);
    var arg1 = '1';
    //相当于
    var arg1;
    console.log(arg1);
    arg1 = '1';
    
    //无变量提升 - 先声明再使用
    console.log(arg2);
    const arg2 = '2';  //not defined
    var arg1 = '1'
    console.log(window.arg1); // 1
    
    //const 非全局作用域, 不在windiow中
    const arg2 = '1';
    console.log(window.arg2);  // undefined  

4. dead zone

    //在声明之前,变量都是不可用的
    if (true) {
      arg1 = '2'; 
      console.log(arg1); // ReferenceError
      let arg1; 
    }

5. let or const

  • 引用型 const
    const obj = {
        name: '张三'age: 18
    }
    obj.name = '李四';
    
    const arr = ['A','B']
    arr[0] = 'C'
    //引用类型的原理 - 指向地址
    
    //如何把对象变成常量不可改变? - object.freeze()
    object.freeze(obj);
    
      const obj2 = {
          name: '张三'age:18,
          class:['语文','数学']
      }
      object.freeze(obj2);
      obj2.class['0'] = '英语';
      
      //freeze只能冻结根层, 嵌套引用类型需要遍历(递归)
      function deepFreeze(){
          //2. 确定主执行步骤
          Object.freeze(obj);
          //3. 逐级深入
          (Object.keys(obj) || [] ).forEach(key =>{
              let innerObj = obj[key]
              if(typeof innerObj === 'object'){
                  //1. 递归模式确定
                  deepFreeze(innderObj);
              }
          })
      }

箭头函数

箭头函数的写法

    //传统函数
    function test(a, b) {
        return a + b;
    }
    const test2 = function(a, b){
        return a + b;
    }
    //ES6
    const test3 = (a, b)=>{
        return a + b;
    }
    const test4 = (a, b)=> a + b;
    const test5 = x => {
        //content
    }
    const test6 = ()=>{
        // ...
    }

上下文

    const obj = {
          name: '张三'age:18,
          class:['语文','数学'],
          getName: function() {
              console.log(this.name);  //张三 - this指向的是obj
              return this.name;
          },
          getAge: ()=>{
              console.log(this.age);  //undefined - this指向的是全局
              return this.age;
          }
      }

箭头函数并不会行成独立上下文, 内部this指向了window。

  • 场景1: dom操作callback时
    const btn = document.querySelector('#btn');
    btn.addEventListener('click',funtion(){
        this.style.color = '#FFF';
    })
  • 场景2: 类操作
    function Obj(teacher, leader){
        this.teacher = teacher;
        this.leader = leader;
    }
     const Obj=(teacher, leader){
        this.teacher = teacher;
        this.leader = leader;
    }
    const o1 = new Ojb('张三', '李四');
    console.log(o1)
    //箭头函数无法成为完整构造类
    
    Obj.prototype.learn = function(){
        console.log(this.teacher, this.leader);
    }
    Obj.prototype.learn = ()=>{
        console.log(this.teacher, this.leader);
    }
    //箭头函数无法成为完整构造原型方法 - 本质原因:this指向的是window

箭头函数的参数特性 - 无法使用arguments

    const test = function(name){
        console.log(arguments);
    }
    
    const test = name =>{
        console.log(arguments); //箭头函数没有arguments
    }

class

class 助力js 更面向对象 - 类

    // 传统对象 - function
    function Course(name, age){
        this.name = name;
        this.age = age;
    }
    Course.prototyper.getCourse = function(){
        return `name is:${this.name},age:${this.age}`;
    }
    const course = new Course('张三', 18);
    course.getCourse()
    
    //ES6
    class Course {
        // init 实例会默认执行
        constructor(name, age){
            this.name = name;
            this.age = age;
        }
        //拓展方法
        getCourse(){
            return `name is:${this.name},age:${this.age}`;
        }
    }
    const course = new Course('张三', 18);
    course.getCourse()
  • 问题1: class的类型
    console.log(typeOf Course);  // function
  • 问题2: class的prototype
    console.log(Course.prototype); // 有区别,但本质类型相同
  • 问题3: class & 函数对象 的属性
    console.log(course.hasOwnProperty('name')); // true
  • 问题4: 属性定义 构造器 & 顶层定义 两种定义方式
    class Course {
        // init 实例会默认执行
        constructor(name, age){
            this.name = name;
            this.age = age;
        }
        //拓展方法
        getCourse(){
            return `name is:${this.name},age:${this.age}`;
        }
        get teacher(){
            return this.name;
        }
        set teacher(val){
            this.name = val
        }
    }
    
    // 1. 如何建立一个只读变量
     class Course {
        // init 实例会默认执行
        constructor(name, age){
            this._name = name;
            this.age = age;
        }
        //拓展方法
        getCourse(){
            return `name is:${this.name},age:${this.age}`;
        }
        get teacher(){
            return this.name;
        }
    }
    
    // 2. js如何建立一个私有属性
    class Course {
        // init 实例会默认执行
        constructor(name, age){
            this._name = name;
            // 在constructor 作用域内定义一个局部变量
            let _age = '123';
            // 内部通过闭包的形式暴露该变量
            this.getCourse = ()=>{
                return _age;
            }
        }
    }
    
    // 3. 封装核心 - 适配器模式
    class utils{
        constructor(core){
            this._main = core;
            this._name = 'my_utils';
            this._id = '不让修改的id'
        }
        get name(){
            return {
                ...this.main.name,
                name: `name is: ${this._name}`
            }
        }
        get id(){
            return {
                ...this.main.id,
                id: this._id
            }
        }
        set name(val){
            // valid  saftey
            this._name = val
        }
    }
    
  • 问题5: 静态方法 - 直接挂载在类上的方法, 无需实例化获取
    class Course{
        constructor(){
            // ...
        }
        static ring(){
            // ...
        }
    }
    Course.ring();
    
  • 问题6: 继承
    class Course{
        constructor(){
            // ...
        }
        static ring(){
            // ...
        }
        send(){}
    }
    class Child extends Course{
        constructor(){
            super()
        }
        fun() {}
    }
    

解构

    const shool = {
        teacher:{
            name:'',
            age:30
        },
        leader:'',
        name:'E'
    }
    
    const {
        teacher:{
            namge,
            age
        },
        leader,
        name:className
    } = shool

    1. 结构使用场景
     //  形参结构
    const sum = arr =>{
        let res = 0;
        arr.forEach(each =>{
            res += each;
        })
    }
    
    //  结合初始值
    const course = ({ teacher, leader, course = 'E'})=>{
        // ...
    }
    course({
        teacher:'AA',
        leader:'BB'
    })
    
    // 返回值
    const getCourse = () => {
        return {
            teacher:'',
            leader:''
        }
    }
    const { teacher, leader } = getCourse();
    
    // 变量交换
    let a = 1;
    let b = 2;
    [b, a]= [a, b]
    
    //json处理
    const json = "{ 'teacher': 'AA', 'leader': 'BB' }";
    const {
        teacher,
        leader
    } = JSON.parse(json)
    
    // ajax
    const {
        code,
        data,
        msg
    } = response;