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

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

无论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-cha...

未登录用户
全部评论0
到底啦