资讯专栏INFORMATION COLUMN

React Native填坑之旅--class(番外篇)

TwIStOy / 2923人阅读

摘要:构造函数定义侦探类作为例子。里的既是类的定义,也是构造函数。在构造函数中定义的实例方法和属性在每一个实例中都会保留一份,而在原型中定义的实例方法和属性是全部实例只有一份。

无论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 # 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继承的时候需要注意两个地方:

需要在子类的构造函数里调用SuperClass.call(this[, arg1, arg2, ...])

子类的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-cha...

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/80669.html

相关文章

  • React Native填坑之旅--HTTP请求篇

    摘要:填坑之旅篇填坑之旅动画填坑之旅请求篇如果不能从头到尾的建立一个应用,那么将失色不少。随着,内置的支持了这个填补回调地狱大坑的功能。很好的利用了这一点,它的请求返回结果就是。在界面上显示异常用,显示警告使用。 React Native填坑之旅--Button篇React Native填坑之旅--动画React Native填坑之旅--HTTP请求篇 如果不能从头到尾的建立一个RN应用,那...

    yexiaobai 评论0 收藏0
  • 写给想做前端的你

    摘要:不过细想想,我邮只有前端的选修课啥的,课程也不是那么就业导向。至少目前,很少有大公司完全把作为前后端通用的技术栈。不能把简单看做是在服务端的延展。编译这个思想在前端领域很重要不改变现有的语言环境同时进行最佳的工程实践。 P.S. 喷神请绕道,大神勿喷,不引战,不攻击,不钻牛角尖。 大二时第一次接触前端。许多同学估计都想过要做一个网站,大部分又是从PHP开始的(谁让它是世界上最好的语言呢...

    JerryWangSAP 评论0 收藏0
  • PostCSS自学笔记(二)【外篇二】

    摘要:之前有研究过做过假设,在插件列表中,的插件执行顺序自上而下,一切看起来似乎是没有任何问题的。再有摘自深入设计摘自写的姿势这两张图则应该是说明了我之前的假设,插件中的执行顺序自上而下。先来看看一片来自的这段会不会跟这个有关呢,我先埋个伏笔。 图解PostCSS的插件执行顺序 文章其实是一系列的早就写完了. 才发现忘了发在SegmentFault上面, 最早发布于https://gitee...

    FleyX 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<