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里的 属性看看这个侦探是从哪本书出来的。 ES5: ES5Detective.prototype.fromBookName = 'who'; ES6: class ES6Detective { detectiveName: string; _bookName: string; constructor() { console.log('Detective constructor'); this.detectiveName = 'Detective who'; // 属性 } } ES6 getter & setterclass 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继承的时候需要注意两个地方:
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类内容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 在子类 甚至,可以在子类里调用父类的静态方法: 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... (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |