zoukankan      html  css  js  c++  java
  • React Native填坑之旅--class(番外篇)

    无论React还是RN都已经迈入了ES6的时代,甚至凭借Babel的支持都进入了ES7。ES6内容很多,本文主要讲解类相关的内容。

    构造函数

    定义侦探类作为例子。

    ES5的“类”是如何定义的。

    function ES5Detective() {
      console.log('##ES5Detective contructor');
    }
    

    ES6定义类:

    class ES6Detective {
      constructor() {
        console.log('Detective constructor');
      }
    }
    

    ES6使用了class关键字,而且有专门的constructor。ES5里的function ES5Detective既是类的定义,也是构造函数。

    属性

    看看这个侦探是从哪本书出来的。

    ES5:

    ES5Detective.prototype.fromBookName = 'who';
    

    ES6:

    class ES6Detective {
      detectiveName: string;
      _bookName: string;
    
      constructor() {
        console.log('Detective constructor');
        this.detectiveName = 'Detective who'; // 属性
      }
    }
    

    ES6 getter & setter

    class ES6Detective {
      detectiveName: string;
      _bookName: string;
    
      constructor() {
        console.log('Detective constructor');
        this.detectiveName = 'Detective who';
        this._bookName = 'who';
      }
    
      get fromBookName() {
        return this._bookName;
      }
    
      set fromBookName(value) {
        this._bookName = value;
      }
    }
    

    如果只有getter没有setter而赋值的话就会出现下面的错误:

    detective.bookAuthor = 'A C';
                         ^
    
    TypeError: Cannot set property bookAuthor of #<ES6Detective> which has only a getter
    

    实例方法

    侦探是如何解决案件的。

    ES5:

    ES5Detective.prototype.solveCase = function(caseName) {
      var dn = this.dectiveName;
      if(!caseName) {
        console.log('SOLVE CASE: ' + dn + ' no case to solve');
      } else {
        console.log('SOLVE CASE: ' + dn + ' get case ' + caseName + ' is solved');
      }
    };
    

    或者:

    function ES5Detective() {
      this.dectiveName = 'Detective who';
      console.log('##ES5Detective contructor');
      // 实例方法
      this.investigate = function(scene) {
        console.log('investigate ' + scene);
      }
    
      this.assistant = "assistant who";
    }
    

    ES6:

    class ES6Detective {
      detectiveName: string;
      _bookName: string;
    
      constructor() {
        console.log('Detective constructor');
        this.detectiveName = 'Detective who';
        this._bookName = 'who';
      }
    
      solveCase(caseName) {
        if(!caseName) {
          console.log('no case to solve');
        } else {
          console.log('case ' + caseName + ' is solved');
        }
      }
    }
    

    ES6添加方法非常简单直接。ES5中添加实例方法有两种方法,一是在prototype里定义,一是在构造函数重定义。在构造函数中定义的实例方法和属性在每一个实例中都会保留一份,而在原型中定义的实例方法和属性是全部实例只有一份

    另外,在ES5的构造函数重定义的实例方法可以访问类的私有变量。比如:

    function ES5Detective() {
      console.log('##ES5Detective contructor');
    
      var available: boolean = true; // private field. default income is ZERO.
      this.investigate = function(scene) {
        if (available) {
          console.log('investigate ' + scene);
        } else {
          console.log(`i'm not available`);
        }
      }
    }
    

    在其他的方法访问的时候就会报错。

    if (!available) {
         ^
    
    

    静态方法

    ES5:

    ES5Detective.countCases = function(count) {
      if(!count) {
        console.log('no case solved');
      } else {
        console.log(`${count} cases are solved`);
      }
    };
    

    类名后直接定义方法,这个方法就是静态方法。

    ES5Detective.countCases();
    

    ES6:

    class ES6Detective {
      static countCases() {
        console.log(`Counting cases...`);
      }
    }
    
    // call it
    ES6Detective.countCases();
    

    继承

    ES6使用extends关键字实现继承。

    ES5:

    function ES5Detective() {
      var available: boolean = true; // private field.
    
      this.dectiveName = 'Detective who';
      console.log('##ES5Detective contructor');
    
      this.investigate = function(scene) {
        // 略 
      }
    
      this.assistant = "assistant who";
    }
    
    ES5Detective.prototype.solveCase = function(caseName) {
      // 略
    }
    
    // inheritance
    function ES5DetectiveConan() {
      // first line in constructor method is a must!!!
      ES5Detective.call(this);
    
      this.dectiveName = 'Conan';
    }
    
    // inheritance
    ES5DetectiveConan.prototype = Object.create(ES5Detective.prototype);
    ES5DetectiveConan.prototype.constructor = ES5DetectiveConan;
    

    ES5继承的时候需要注意两个地方:

    1. 需要在子类的构造函数里调用SuperClass.call(this[, arg1, arg2, ...])
    2. 子类的prototype赋值为:SubClass.prototype = Object.create(SuperClass.prototype),然后把构造函数重新指向自己的:SubClass.prototpye.constructor = SubClass

    ES6:

    class ES6Detective {
      constructor() {
        console.log('Detective constructor');
        this.detectiveName = 'Detective who';
        this._bookName = 'who';
      }
    
      solveCase(caseName) {
        if(!caseName) {
          console.log('no case to solve');
        } else {
          console.log('case ' + caseName + ' is solved');
        }
      }
    
      get fromBookName() {
        return this._bookName;
      }
    
      set fromBookName(value) {
        this._bookName = value;
      }
    
      get bookAuthor() {
        return 'Author Who';
      }
    
      static countCases() {
        console.log(`Counting cases...`);
      }
    }
    
    class ES6DetectiveConan extends ES6Detective {
      constructor() {
        super();
        console.log('ES6DetectiveConan constructor');
      }
    }
    

    ES6的新语法更加易懂。

    注意:一定要在子类的构造方法里调用super()方法。否则报错。

    调用super类内容

    class ES6DetectiveConan extends ES6Detective {
      constructor() {
        super();
        console.log('ES6DetectiveConan constructor');
      }
    
      solveCase(caseName) {
        super.solveCase(caseName);
    
        if(!caseName) {
          console.log('CONAN no case to solve');
        } else {
          console.log('CONAN case ' + caseName + ' is solved');
        }
      }
    }
    

    静态方法可以被继承

    ES6的静态方法可以被继承。ES5的不可以。

    class ES6Detective {
      static countCases(place) {
        let p = !place ? '[maybe]' : place;
        console.log(`Counting cases...solve in ${p}`);
      }
    }
    
    class ES6DetectiveConan extends ES6Detective {
      constructor() {
        super();
        console.log('ES6DetectiveConan constructor');
      }
    }
    
    // static method
    ES6Detective.countCases();
    ES6DetectiveConan.countCases('Japan');
    
    // result
    Counting cases...solve in [maybe]
    Counting cases...solve in Japan
    

    在子类ES6DetectiveConan并没有定义任何方法,包括静态方法。但是,在父类和子类里都可以调用该方法。

    甚至,可以在子类里调用父类的静态方法:

    class ES6DetectiveConan extends ES6Detective {
      static countCases(place) {
        let p = !place ? '[maybe]' : place;
        super.countCases(p);
        console.log(`#Sub class:- Counting cases...solve in ${p}`);
      }
    }
    
    // result
    Counting cases...solve in [maybe]
    Counting cases...solve in Japan
    #Sub class:- Counting cases...solve in Japan
    

    代码

    https://github.com/future-challenger/ES-Samples/tree/master/class

  • 相关阅读:
    java.lang.NoSuchMethodError: org.springframework.core.io.ResourceEditor错误
    http://blog.sina.com.cn/s/blog_6145ed810102vr8k.html
    异或巧用:Single Number
    Highcharts:X轴分组堆叠图
    Vs2012在Linux开发中的应用(5):项目属性的定义
    BZOJ 1005 明明的烦恼 Prufer序列+组合数学+高精度
    Python 点滴 I
    easyUI 验证控件应用、自己定义、扩展验证 手机号码或电话话码格式
    InnoDB: Error: io_setup() failed with EAGAIN after 5 attempts
    Java设计模式-设计模式的六种原则
  • 原文地址:https://www.cnblogs.com/sunshine-anycall/p/5965550.html
Copyright © 2011-2022 走看看