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里的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

欢迎加群互相学习,共同进步。QQ群:iOS: 58099570 | Android: 572064792 | Nodejs:329118122 做人要厚道,转载请注明出处!















本文转自张昺华-sky博客园博客,原文链接:http://www.cnblogs.com/sunshine-anycall/p/5965550.html ,如需转载请自行联系原作者

相关文章
|
前端开发 JavaScript
React_函数式Hooks和Class比较优缺点
React Hooks与Class组件都能返回JSX并接收props,但Hooks无`this`指向问题,用`useEffect`模拟生命周期,`memo`优化性能,状态更新用`useState`;Class组件通过生命周期方法、`PureComponent`或`shouldComponentUpdate`优化,状态用`this.state`和`this.setState`管理。
161 1
React_函数式Hooks和Class比较优缺点
|
开发框架 Dart 前端开发
【Flutter前端技术开发专栏】Flutter与React Native的对比与选择
【4月更文挑战第30天】对比 Flutter(Dart,强类型,Google支持,快速热重载,高性能渲染)与 React Native(JavaScript,庞大生态,热重载,依赖原生渲染),文章讨论了开发语言、生态系统、性能、开发体验、学习曲线、社区支持及项目选择因素。两者各有优势,选择取决于项目需求、团队技能和长期维护考虑。参考文献包括官方文档和性能比较文章。
535 0
【Flutter前端技术开发专栏】Flutter与React Native的对比与选择
|
XML JavaScript 前端开发
学习react基础(1)_虚拟dom、diff算法、函数和class创建组件
本文介绍了React的核心概念,包括虚拟DOM、Diff算法以及如何通过函数和类创建React组件。
156 3
|
Dart 前端开发 JavaScript
探索移动应用开发中的跨平台解决方案:Flutter与React Native的比较
在移动应用开发领域,选择合适的跨平台解决方案是关键。本文将深入分析Flutter和React Native这两大主流框架,从性能、开发效率、社区支持等方面进行比较,帮助开发者做出明智的选择。
265 27
|
前端开发 JavaScript Android开发
React Native跨平台开发实战
【7月更文挑战第21天】React Native为跨平台移动应用开发提供了一种高效且强大的解决方案。通过本文的学习,你应该能够掌握React Native的基本概念和实战步骤,并开始在你的项目中使用React Native进行开发。随着你对React Native的深入理解,你将能够利用其强大的功能来构建更加复杂和高效的移动应用。
|
前端开发 开发者 UED
数据校验的艺术:揭秘JSF如何将前端与后端验证合二为一,打造无缝用户体验
【8月更文挑战第31天】JavaServer Faces(JSF)是构建企业级Web应用的Java规范,提供了丰富的组件和API,便于快速搭建用户界面。JSF验证框架基于JavaBean验证API(JSR 303/JSR 380),利用注解如`@NotNull`、`@Size`等在模型类上定义验证规则,结合前端的`&lt;h:inputText&gt;`和`&lt;h:message&gt;`标签展示错误信息。
158 0
|
前端开发 JavaScript 测试技术
React Hooks vs. Class Components的奥秘:如何用新时代开发模式让你的项目一鸣惊人?
【8月更文挑战第31天】在现代Web开发中,React提供了两种主要的组件实现方式:Hooks和Class Components。React Hooks自16.8版本推出,允许开发者在不使用类的情况下访问状态和生命周期方法,提高了函数组件的功能性和开发效率。Class Components则基于JavaScript类,提供了丰富的生命周期方法,便于精细控制组件行为。尽管两者在代码组织、性能及开发效率上各有千秋,但随着Hooks的普及,前端开发模式正逐渐转变,Hooks因其实现简便性成为越来越多开发者的选择,而在需要细致管理生命周期的场景下,Class Components仍具优势。
135 0
|
开发框架 移动开发 前端开发
【Uniapp 专栏】Uniapp 与 React Native 的对比分析
【5月更文挑战第14天】Uniapp和React Native是热门的跨平台移动开发框架。Uniapp以其一套代码多端运行、丰富的组件生态和较低的学习曲线受到青睐,适合快速开发简单应用。React Native基于React,拥有活跃社区和优秀性能,适合复杂应用。React Native在性能上略胜一筹,尤其在需要接近原生体验的场景。Uniapp的官方组件弥补了社区资源不足。选择时需考虑开发效率、性能需求、团队技术栈和社区支持。
2865 1
【Uniapp 专栏】Uniapp 与 React Native 的对比分析
|
前端开发 自动驾驶 程序员
鸿蒙? 车载?Flutter? React Native? 为什么我劝你三思,说点不一样的
本文探讨了在信息技术快速发展的背景下,开发者如何选择学习路径。作者提倡使用终局思维来规划职业发展,考虑技术的长远影响。终局思维注重长远目标、系统分析、反向规划和动态调整。以车载开发为例,预测未来智能汽车可能由语音助手主导,而非依赖平板界面。此外,作者建议不要过分投入打工状态,应思考创建自己的产品,如App,以实现技能补充和额外收入。选择对未来发展和自主性有益的技术,如Kotlin,比盲目追求热点更为重要。做减法和有标准的选择,能帮助减轻焦虑,实现更高效的成长。关注公众号“AntDream”获取更多相关内容。
317 1
|
开发框架 前端开发 JavaScript
移动应用开发中的跨平台策略:Flutter与React Native的比较
在移动应用领域,跨平台解决方案已成为开发者追求高效、成本效益和广泛覆盖的关键。本文深入探讨了两种领先的跨平台框架——Flutter和React Native,从技术架构、性能、社区生态及实际应用案例四个维度进行全面对比分析。通过这一比较,旨在为移动应用开发者提供选择合适框架的参考依据,帮助他们根据项目需求做出明智的决策。