ReactNative填坑之旅–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繼承的時候需要注意兩個地方:
- 需要在子類的建構函式裡呼叫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
作者:小紅星閃啊閃
來源:51CTO
相關文章
- ReactNative填坑之旅–Navigation篇ReactNavigation
- ReactNative填坑之旅–重新認識RNReact
- ReactNative填坑之旅–與Native通訊之iOS篇ReactiOS
- React Native填坑之旅--GraphQLReact Native
- 編譯icedTea-web報錯填坑之旅編譯Web
- React Native填坑之旅 -- What's nextReact Native
- React Native填坑之旅--使用react-redux hooksReact NativeReduxHook
- React Native填坑之旅--開啟TurboModule(Android)React NativeAndroid
- React Native填坑之旅--多平臺支援之WebReact NativeWeb
- React Native填坑之旅--使用原生檢視AndroidReact NativeAndroid
- 填坑Ⅱ
- React Native填坑之旅 -- 從Native發事件給JSReact Native事件JS
- streamparse 填坑
- 小程式踩坑填坑
- Flutter 填坑整理Flutter
- vim 填坑之路
- Hibernate填坑
- Elasticsearch 填坑記Elasticsearch
- vue微信填坑Vue
- javascript 填坑史JavaScript
- React 填“坑”記React
- Date填坑記
- Flutter for web 最新填坑FlutterWeb
- 小程式花式填坑
- 05-待填坑...
- compilephpwithopensslonmacosxerror填坑CompilePHPMacError
- Flutter填坑全面總結Flutter
- OpenJFX編譯填坑之路編譯
- 小程式填坑實錄
- 微信小程式填坑心路微信小程式
- React Native 填坑指南React Native
- vuepress爬坑之旅Vue
- ReactNative 踩坑之 iOS 原生元件ReactiOS元件
- 重啟React Native老專案的奇幻之旅:填坑實錄與解決方案分享React Native
- Java填坑系列之LinkedListJava
- minikube windows hyperx填坑記Windows
- vue 填坑系列總結——scopedVue
- 填坑-關於IIC通訊