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

React Native填坑之旅--class(番外篇)的更多相关文章

  1. React Native填坑之旅--Flow篇(番外)

    flow不是React Native必会的技能,但是作为正式的产品开发优势很有必要掌握的技能之一.所以,算是RN填坑之旅系列的番外篇. Flow是一个静态的检查类型检查工具,设计之初的目的就是为了可以 ...

  2. React Native填坑之旅--与Native通信之iOS篇

    终于开始新一篇的填坑之旅了.RN厉害的一个地方就是RN可以和Native组件通信.这个Native组件包括native的库和自定义视图,我们今天主要设计的内容是native库方面的只是.自定义视图的使 ...

  3. React Native填坑之旅--布局篇

    代码在这里: https://github.com/future-challenger/petshop/tree/master/client/petshop/src/controller 回头看看RN ...

  4. React Native填坑之旅--重新认识RN

    如同黑夜里的一道光一样,就这么知道了F8. F8是每年一次Facebook每年一次的开发者大会.每次大会都会release相应的APP,iOS.Android都有.之前都是用Native开发的,但是2 ...

  5. React Native填坑之旅--组件生命周期

    这次我们来填React Native生命周期的坑.这一点非常重要,需要有一个清晰的认识.如果你了解Android或者iOS的话,你会非常熟悉我们今天要说的的内容. 基本上一个React Native的 ...

  6. React Native填坑之旅--Navigation篇

    React Native的导航有两种,一种是iOS和Android通用的叫做Navigator,一种是支持iOS的叫做NavigatorIOS.我们这里只讨论通用的Navigator.会了Naviga ...

  7. React Native填坑之旅--ListView篇

    列表显示数据,基本什么应用都是必须.今天就来从浅到深的看看React Native的ListView怎么使用.笔者写作的时候RN版本是0.34. 最简单的 //@flow import React f ...

  8. React Native填坑之旅--动画

    动画是提高用户体验不可缺少的一个元素.恰如其分的动画可以让用户更明确的感知当前的操作是什么. 无疑在使用React Native开发应用的时候也需要动画.这就需要知道RN都给我们提供了那些动画,和每个 ...

  9. React Native填坑之旅--Button篇

    从React过来,发现React Native(以下简称RN)居然没有Button.隔壁的iOS是有UIButton的,隔壁的隔壁的Android里也是有的.没有Button,就没有点击效果啊.这还真 ...

  10. React Native填坑之旅 -- 使用iOS原生视图(高德地图)

    在开发React Native的App的时候,你会遇到很多情况是原生的视图组件已经开发好了的.有的是系统的SDK提供的,有的是第三方试图组件,总之你的APP可以直接使用的原生视图是很多的.React ...

随机推荐

  1. FIleText转换为JSONObject对象

    package com.beijxing.TestMain; import java.io.File; import java.io.IOException; import org.apache.co ...

  2. Altium Designer XX 重新定义板框形状和大小的方法

    Altium Designer15 重新定义板框形状和大小的方法:重新定义板框形状和大小的方法.很简单,点击数字键"1",就会看到板框界面变绿了这时候你在去点击菜单栏里的Desig ...

  3. [学习笔记]JS中闭包的理解

    一.闭包概念的理解 闭包,又称为词法闭包或函数闭包指引用了自由变量的函数.这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外. 自由变量:该变量既不是函数本身定义的也不是函数 ...

  4. 【活动】监控宝惹火Docker监控,开放试用中

    要说这两年最火爆的技术有哪些,Docker绝对是其中之一. 有人说,Docker缺少必要的运维监控工具,实践起来有难度. 幸福来的太快了. 云智慧旗下产品监控宝又惹火了,推出重量级新功能——Docke ...

  5. vue路由的简单实例

    vue2.0 和 vue1.0 路由的语法还是有点稍微的差别,下面介绍一下vue-router 2的简单实例: <!DOCTYPE html> <html lang="en ...

  6. Java重点之小白解析--浅谈HashMap与HashTable

    这是一个面试经常遇到的知识点,无论什么公司这个知识点几乎是考小白必备,为什么呢?因为这玩意儿太特么常见了,常见到你写一百行代码,都能用到好几次,不问这个问哪个.so!本小白网罗天下HashMap与Ha ...

  7. ORACLE 日常处理办法

    Oracle删除当前用户下所有的表的方法 1.如果有删除用户的权限,则可以: drop user user_name cascade; 加了cascade就可以把用户连带的数据全部删掉. 删除后再创建 ...

  8. 百度自动发贴,登录很顺利的模拟实现,但发贴攻关失败,能力有限,追JS过程中颇为痛苦

    攻关失败,且短期内看不到希望,看不到方向,且越来越焦急,目前已知的是,用根据用户的鼠标事件以一定的规则结合其他数据,服务器以这些数据验证是否为真正的手动发贴. 不过闲暇时实现了百度贴吧的自动签到. 较 ...

  9. JavaScript基础知识整理(1)

    粗略理解,努力入门中 1.在html中引入外部脚本:  <script src="filename.js"></script> 2.注释:  多于一行的长注 ...

  10. SharePoint中的ASHX

    <%@ Assembly Name="namespace, Version=1.0.0.0, Culture=neutral, PublicKeyToken=key" %&g ...