zoukankan      html  css  js  c++  java
  • 2.ES6引进的新特性——类Class

         

    为什么?

           ES6中引入了类,类在java/c++等面向对象的编程语言常见,JS引入类是为了在日后使用js开发大型的应用程序,类本质是语法糖(语法上更加人性化)

    以前写一个类

    function User(name, age){
       this.name = name;
       this.age = age;
    }
    
    // 静态方法
    User.getClassName = function () {
       return 'User'
    };
    
    // 为类添加公用方法,在原型对象上加
    User.prototype.changeName = function (name) {
       this.name = name
    }
    User.prototype.changeAge = function (age) {
       this.age = age
    }
    
    // 为类添加取值函数与存值函数(都要写到原型对象上去)
    Object.defineProperty(User.prtotype, 'info', {
       get(){
          return 'name:' + this.name + ' | age:' + this.age;
       }
    });
    
    
    // 新建一个子类
    function Manager(name, age, password){
       User.call(this,name,age);  // 也可以User.apply(this, arguments),意思是调用父类的构造函数,从而达到继承父类属性的效果,注意,只能继承父类实例属性,而继承不了父类的方法
       this.password = password;
    }
    // 继承静态方法
    Manager._proto_ = User;
    // 继承prototype方法(继承父类方法)
    Manager.prototype = User.prototype; // 也可以Manager.prototype = new User()
    // 添加新方法
    Manager.prototype.changePassword = function(pwd){
       this.password = password;
    };
    
    // 验证是否能继承
    var manager = new Manager('kkk', 22, '123');
    manager.changeName('lighter');
    console.log(manager.name)   //  输出 lighter
    console.log(manager.info);  //  输出 name:lighter | age:22
    

      

    可以看出,以前ES5写一个类,虽然可以实现类的继承,但是很不优雅--!

    ES6优雅写类

    我们来注释上面的代码,一段一段地看它们又什么区别

    //function User(name, age){
    //   this.name = name;
    //   this.age = age;
    //}
    
    class User{
       constructor(name, age){
           this.name = name;
           this.age = age;
       }
    
    
    
        //// 静态方法
        //User.getClassName = function () {
        //   return 'User'
        //};
        
        // 静态方法
        User.getClassName = function () {
            return 'User';
        }
    
    
        
        //// 为类添加公用方法,在原型对象上加
        //User.prototype.changeName = function (name) {
        //   this.name = name
        //}
        //User.prototype.changeAge = function (age) {
        //   this.age = age
        //}
    
        // 为类添加公用方法,在原型对象上加
        changeName(name) {
            this.name = name
        }
        changeAge(age) {
            this.age= age
        }
    
    
    
        //// 为类添加取值函数与存值函数(都要写到原型对象上去)
        //Object.defineProperty(User.prtotype, 'info', {
        //   get(){
        //      return 'name:' + this.name + ' | age:' + this.age;
        //   }
        //});
    
        // 为类添加取值函数与存值函数(都要写到原型对象上去)
        get info() {
            return 'name:' + this.name + ' | age:' + this.age;
        }
    
    }
    
    
    // 新建一个子类
    //function Manager(name, age, password){
    //   User.call(this,name,age);
    //   this.password = password;
    //}
    //// 继承静态方法,原型链就是实力对象_proto_属性
    //Manager._proto_ = User;
    //// 继承prototype方法
    //Manager.prototype = User.prototype;
    
    
    class Manager extends User{
        constructor(name, age, password){
            super(name,age);
            this.password = password;
        }
    
        //// 添加新方法
        //Manager.prototype.changePassword = function(pwd){
        //   this.password = password;
        //};    
    
        changePassword(password){
            this.password = password
        }
    }
    
    
    
    // 然后下面的用法都是一样的。
    
    
    // 验证是否能继承
    var manager = new Manager('kkk', 22, '123');
    manager.changeName('lighter');
    console.log(manager.name)   //  输出 lighter
    console.log(manager.info);  //  输出 name:lighter | age:22
    

     

     语法糖

    注意,例如上面写的class 等概念,就是语法糖,它方便了我们写代码,使得代码更加地简洁,无论是class User ,还是class Manager,它们本质都是function

    console.log(typeof User, typeof Manager);
    
    //输出  function   function
    

    简写继承

    class I extends User {  
    }
    var me = new I('psg', 23);
    console.log(me);
    
    //不报错,输出   I {name: 'psg', age: 23}

    上面继承没加构造函数constructor,但是内部默认会加,上面的代码会变成下面这个样子:

    class I extends User{
        constructor(...arg){
            super(...arg);
        }  
    }
    

    总结ES6继承的重点

    1.继承时候,如果手写构造函数,那么在constructor块里面,第一行写super(....),因为它要先创建父类的对象,然后所有的方法(上面的changePassword)、属性(上面的password)都会加到父类创建的对象上。

    2.使用super可以改变父类的方法,例如上面的Manager类,它继承User父类,现在我想改变从父类中继承的info方法,我加一点东西,使我Manager有别于父类,但是我还是调用同样父类方法的名字,这时我可以这样写:

    class Manager extends User{
        constructor(name, age, password){
            super(name,age);
            this.password = password;
        }
    
        //// 添加新方法
        //Manager.prototype.changePassword = function(pwd){
        //   this.password = password;
        //};    
    
        changePassword(password){
            this.password = password
        }
        //使用super改写父类的方法
        get info() {
            var info = super.info;  // 注意!!这里的info没有()
            console.log(info);
            return info + '--new'
        }
    }
    var manager = new Manager('kkk', 22, '123');
    console.log(manager.info);  
    // 输出 name:lighter | age:22
    //  输出 name:lighter | age:22---new

      

    创建立即执行的类

    'use strict'
    let user = new class User{
        constructor(name){
            this.name = name;  
        }
    }('psg');
    
    console.log(user);
    
    //输出 User {name: 'psg'}
    

      

    不被提升

    'use strict'
    
    var user = new User();
    
    class User{
        constructor(name){
            this.name = name;  
        }
    }
    
    console.log(user);
    
    //ReferenceError: User is not defined
    

      

    -----完-----

    不安逸,不浮躁,牛B就是一个学习累积的过程
  • 相关阅读:
    Nmap帮助文档解释
    用servlet设置过滤器处理中文乱码
    Linux服务器远程连接window服务器并执行cmd命令
    java中的异常处理
    java的反射机制
    react入门
    多线程编程
    软件工程基本概念
    反射、类加载与垃圾回收
    数据库
  • 原文地址:https://www.cnblogs.com/pengshengguang/p/7732932.html
Copyright © 2011-2022 走看看