原文地址:http://www.devio.org/2016/08/11/React-Native%E4%B9%8BReact%E9%80%9F%E5%AD%A6%E6%95%99%E7%A8%8B-(%E4%B8%8B)/

ES6的特性

何为ES6?

ES6全称ECMAScript 6.0,ES6于2015年6月17日发布,ECMAScript是ECMA制定的标准化脚本语言。目前JavaScript使用的ECMAScript版本为ECMAScript-262。

下面我为大家列举了ES6新特性中对我们开发影响比较大的六方面的特性。

1.类(class)

对熟悉Java,object-c,c#等纯面向对象语言的开发者来说,都会对class有一种特殊的情怀。ES6 引入了class(类),让JavaScript的面向对象编程变得更加简单和易于理解。

  1. class Animal {
  2. // 构造方法,实例化的时候将会被调用,如果不指定,那么会有一个不带参数的默认构造函数.
  3. constructor(name,color) {
  4. this.name = name;
  5. this.color = color;
  6. }
  7. // toString 是原型对象上的属性
  8. toString() {
  9. console.log('name:' + this.name + ',color:' + this.color);
  10. }
  11. }
  12. var animal = new Animal('dog','white');//实例化Animal
  13. animal.toString();
  14. console.log(animal.hasOwnProperty('name')); //true
  15. console.log(animal.hasOwnProperty('toString')); // false
  16. console.log(animal.__proto__.hasOwnProperty('toString')); // true
  17. class Cat extends Animal {
  18. constructor(action) {
  19. // 子类必须要在constructor中指定super 方法,否则在新建实例的时候会报错.
  20. // 如果没有置顶consructor,默认带super方法的constructor将会被添加、
  21. super('cat','white');
  22. this.action = action;
  23. }
  24. toString() {
  25. console.log(super.toString());
  26. }
  27. }
  28. var cat = new Cat('catch')
  29. cat.toString();
  30. // 实例cat 是 Cat 和 Animal 的实例,和Es5完全一致。
  31. console.log(cat instanceof Cat); // true
  32. console.log(cat instanceof Animal); // true

2.模块(Module)

ES5不支持原生的模块化,在ES6中,模块将作为重要的组成部分被添加进来。模块的功能主要由 export 和 import 组成。每一个模块都有自己单独的作用域,模块之间的相互调用关系是通过 export 来规定模块对外暴露的接口,通过import来引用其它模块提供的接口。同时还为模块创造了命名空间,防止函数的命名冲突。

导出(export)

ES6允许在一个模块中使用export来导出多个变量或方法。

导出变量

  1. //test.js
  2. export var name = 'Rainbow'

心得:ES6不仅支持变量的导出,也支持常量的导出。 export const sqrt = Math.sqrt;//导出常量

ES6将一个文件视为一个模块,上面的模块通过 export 向外输出了一个变量。一个模块也可以同时往外面输出多个变量。

  1. //test.js
  2. var name = 'Rainbow';
  3. var age = '24';
  4. export {name, age};

导出函数

  1. // myModule.js
  2. export function myModule(someArg) {
  3. return someArg;
  4. }

导入(import)

定义好模块的输出以后就可以在另外一个模块通过import引用。

  1. import {myModule} from 'myModule';// main.js
  2. import {name,age} from 'test';// test.js

心得:一条import 语句可以同时导入默认方法和其它变量。import defaultMethod, { otherMethod } from 'xxx.js';

3.箭头(Arrow)函数

这是ES6中最令人激动的特性之一。=>不只是关键字function的简写,它还带来了其它好处。箭头函数与包围它的代码共享同一个this,能帮你很好的解决this的指向问题。有经验的JavaScript开发者都熟悉诸如var self = this;var that = this这种引用外围this的模式。但借助=>,就不需要这种模式了。

箭头函数的结构

箭头函数的箭头=>之前是一个空括号、单个的参数名、或用括号括起的多个参数名,而箭头之后可以是一个表达式(作为函数的返回值),或者是用花括号括起的函数体(需要自行通过return来返回值,否则返回的是undefined)。

  1. // 箭头函数的例子
  2. ()=>1
  3. v=>v+1
  4. (a,b)=>a+b
  5. ()=>{
  6. alert("foo");
  7. }
  8. e=>{
  9. if (e == 0){
  10. return 0;
  11. }
  12. return 1000/e;
  13. }

心得:不论是箭头函数还是bind,每次被执行都返回的是一个新的函数引用,因此如果你还需要函数的引用去做一些别的事情(譬如卸载监听器),那么你必须自己保存这个引用。

卸载监听器时的陷阱

错误的做法

  1. class PauseMenu extends React.Component{
  2. componentWillMount(){
  3. AppStateIOS.addEventListener('change', this.onAppPaused.bind(this));
  4. }
  5. componentWillUnmount(){
  6. AppStateIOS.removeEventListener('change', this.onAppPaused.bind(this));
  7. }
  8. onAppPaused(event){
  9. }
  10. }

正确的做法

  1. class PauseMenu extends React.Component{
  2. constructor(props){
  3. super(props);
  4. this._onAppPaused = this.onAppPaused.bind(this);
  5. }
  6. componentWillMount(){
  7. AppStateIOS.addEventListener('change', this._onAppPaused);
  8. }
  9. componentWillUnmount(){
  10. AppStateIOS.removeEventListener('change', this._onAppPaused);
  11. }
  12. onAppPaused(event){
  13. }
  14. }

除上述的做法外,我们还可以这样做:

  1. class PauseMenu extends React.Component{
  2. componentWillMount(){
  3. AppStateIOS.addEventListener('change', this.onAppPaused);
  4. }
  5. componentWillUnmount(){
  6. AppStateIOS.removeEventListener('change', this.onAppPaused);
  7. }
  8. onAppPaused = (event) => {
  9. //把方法直接作为一个arrow function的属性来定义,初始化的时候就绑定好了this指针
  10. }
  11. }

需要注意的是:不论是bind还是箭头函数,每次被执行都返回的是一个新的函数引用,因此如果你还需要函数的引用去做一些别的事情(譬如卸载监听器),那么你必须自己保存这个引用。

4.ES6不再支持Mixins

在ES5下,我们经常使用mixin来为组件添加一些新的方法,如:

  1. var SetIntervalMixin = {
  2. componentWillMount: function() {
  3. this.intervals = [];
  4. },
  5. setInterval: function() {
  6. this.intervals.push(setInterval.apply(null, arguments));
  7. },
  8. componentWillUnmount: function() {
  9. this.intervals.forEach(clearInterval);
  10. }
  11. };
  12. var TickTock = React.createClass({
  13. mixins: [SetIntervalMixin], // Use the mixin
  14. getInitialState: function() {
  15. return {seconds: 0};
  16. },
  17. ...

但,很不幸的是,ES6不支持使用Mixins了,不过我们可以使用,增强组件来替代Mixins。

  1. //Enhance.js
  2. import { Component } from "React";
  3. export var Enhance = ComposedComponent => class extends Component {
  4. constructor() {
  5. this.state = { data: null };
  6. }
  7. componentDidMount() {
  8. this.setState({ data: 'Hello' });
  9. }
  10. render() {
  11. return <ComposedComponent {...this.props} data={this.state.data} />;
  12. }
  13. };
  14. //HigherOrderComponent.js
  15. import { Enhance } from "./Enhance";
  16. class MyComponent {
  17. render() {
  18. if (!this.data) return <div>Waiting...</div>;
  19. return <div>{this.data}</div>;
  20. }
  21. }
  22. export default Enhance(MyComponent); // Enhanced component

用一个“增强组件”,来为某个类增加一些方法,并且返回一个新类,这无疑能实现mixin所实现的大部分需求。

另外,网上也有很多其他的方案,如react-mixin

5.ES6不再有自动绑定

在ES5中,React.createClass会把所有的方法都bind一遍,这样可以提交到任意的地方作为回调函数,而this不会变化。但在ES6中没有了自动绑定,也就是说,你需要通过bind或者箭头函数来手动绑定this引用。

  1. // 通过使用 bind() 来绑定`this`
  2. <div onClick={this.tick.bind(this)}>
  3. // 也可通过使用箭头函数来实现
  4. <div onClick={() => this.tick()}>

心得: 因为无论是箭头函数还是bind()每次被执行都返回的是一个新的函数引用,所以,推荐大家在组件的构造函数中来绑定this

```javascript constructor(props) { super(props); this.state = {count: props.initialCount}; this.tick = this.tick.bind(this);//在构造函数中绑定this } // 使用

<div onClick={this.tick}>


  1. ### 6.static关键字
  2. ES6中我们可以通过static关键字来定义一个类函数。
  3. ```javascript
  4. class People {
  5. constructor(name) { //构造函数
  6. this.name = name;
  7. }
  8. sayName() {
  9. console.log(this.name);
  10. }
  11. static formatName(name) //将formatName定义为类方法
  12. return name[0].toUpperCase() + name.sustr(1).toLowerCase();
  13. }
  14. }
  1. console.log(People.formatName("tom")); //使用类方法formatName

ES6 VS ES5(ES6与ES5的区别)

新版本的React /React Native使用了ES6标准,下面就让我们一起了解一下基于ES6的React/React Native相比ES5有哪些不同。

心得:很多React/React Native的初学者经常会被ES6问题迷惑:官方建议我们ES6,但是网上搜到的很多教程和例子都是基于ES5版本的,所以很多人感觉无法下手,下面就让我们一起认识ES6与ES5在React/React Native开发上有哪些不同和需要注意的地方。

下面是我们需要知道的ES6与ES5在4大方面上的区别。

1.在定义方面的不同

在定义组件,方法,属性等方面,ES6与ES5是有所不同的,下面就让我们一起看一下有哪些不同。

心得:因为向下兼容的原因,你在开发过程中可使用ES6也可以使用ES5的规范,但为了代码的风格一致性,建议尽量减少混写。

定义组件

ES5

在ES5里,通常通过React.createClass来定义一个组件类,像这样:

  1. var Photo = React.createClass({
  2. render: function() {
  3. return (
  4. <Image source={this.props.source} />
  5. );
  6. },
  7. });

ES6

在ES6里,我们通过继承React.Component 来定义一个组件类,像这样:

  1. class Photo extends React.Component {
  2. render() {
  3. return (
  4. <Image source={this.props.source} />
  5. );
  6. }
  7. }

定义方法

相比ES5,ES6在方法定义上语法更加简洁,从上面的例子里可以看到,给组件定义方法不再用 名字: function()的写法,而是直接用名字(),在方法的最后也不能有逗号了。

ES5

  1. var Photo = React.createClass({
  2. test: function(){
  3. },
  4. render: function() {
  5. return (
  6. <Image source={this.props.source} />
  7. );
  8. },
  9. });

ES6

  1. class Photo extends React.Component {
  2. test() {
  3. }
  4. render() {
  5. return (
  6. <Image source={this.props.source} />
  7. );
  8. }
  9. }

定义组件的属性类型和默认属性

ES5

在ES5里,属性类型和默认属性分别通过propTypes成员和getDefaultProps方法来实现。

  1. var Video = React.createClass({
  2. getDefaultProps: function() {
  3. return {
  4. autoPlay: false,
  5. maxLoops: 10,
  6. };
  7. },
  8. propTypes: {
  9. autoPlay: React.PropTypes.bool.isRequired,
  10. maxLoops: React.PropTypes.number.isRequired,
  11. posterFrameSrc: React.PropTypes.string.isRequired,
  12. videoSrc: React.PropTypes.string.isRequired,
  13. },
  14. render: function() {
  15. return (
  16. <View />
  17. );
  18. },
  19. });

ES6

在ES6里,可以统一使用static成员来实现。

  1. class Video extends React.Component {
  2. static defaultProps = {
  3. autoPlay: false,
  4. maxLoops: 10,
  5. }; // 注意这里有分号
  6. static propTypes = {
  7. autoPlay: React.PropTypes.bool.isRequired,
  8. maxLoops: React.PropTypes.number.isRequired,
  9. posterFrameSrc: React.PropTypes.string.isRequired,
  10. videoSrc: React.PropTypes.string.isRequired,
  11. }; // 注意这里有分号
  12. render() {
  13. return (
  14. <View />
  15. );
  16. } // 注意这里既没有分号也没有逗号
  17. }

也有人这么写,虽然不推荐,但读到代码的时候你应当能明白它的意思:

  1. class Video extends React.Component {
  2. render() {
  3. return (
  4. <View />
  5. );
  6. }
  7. }
  8. Video.defaultProps = {
  9. autoPlay: false,
  10. maxLoops: 10,
  11. };
  12. Video.propTypes = {
  13. autoPlay: React.PropTypes.bool.isRequired,
  14. maxLoops: React.PropTypes.number.isRequired,
  15. posterFrameSrc: React.PropTypes.string.isRequired,
  16. videoSrc: React.PropTypes.string.isRequired,
  17. };

心得:对React开发者而言,static在一些老版本的浏览器上是不支持的。React Native开发者可以不用担心这个问题。

2.在导入(import)与导出(export)组件上的不同

导入组件

ES5

在ES5里,如果使用CommonJS标准,引入React包基本通过require进行,代码类似这样:

  1. var React = require("react");
  2. var {
  3. Component,
  4. PropTypes
  5. } = React; //引用React抽象组件
  1. var ReactNative = require("react-native");
  2. var {
  3. Image,
  4. Text,
  5. } = ReactNative; //引用具体的React Native组件
  1. var AboutPage=require('./app/AboutPage') //引入app目录下AboutPage组件,即AboutPag.js
  2. var PopularPage=require('./app/PopularPage') //引入app目录下PopularPage组件,即PopularPage.js
  3. var FavoritePage=require('./app/FavoritePage') //引入app目录下FavoritePage组件,即FavoritePage.js

ES6

在ES6里,没有了require,而是使用import来导入组件,有点像Java的写法。

  1. import React, {
  2. Component,
  3. PropTypes,
  4. } from 'react';//引用React抽象组件
  1. import {
  2. Image,
  3. Text
  4. } from 'react-native' //引用具体的React Native组件
  1. import AboutPage from './app/AboutPage' //引入app目录下AboutPage组件,即AboutPag.js
  2. import PopularPage from './app/PopularPage' //引入app目录下PopularPage组件,即PopularPage.js
  3. import FavoritePage from './app/FavoritePage' //引入app目录下FavoritePage组件,即FavoritePage.js

另外,ES6支持将组件导入作为一个对象,使用“ * as”修饰即可。

  1. //引入app目录下AboutPage组件作为一个对象,接下来就可使用“AboutPage.”来调用AboutPage的方法及属性了。
  2. import * as AboutPage from './app/AboutPage'

心得:使用“ * as ”修饰后,导入的组件直接被实例化成一个对象,可以使用“.”语法来调用组件的方法和属性,和没有“ * as ”修饰是有本质区别的,使用的时候要特别注意。

导出组件

ES5
在ES5里,要导出一个类给别的模块用,一般通过module.exports来导出:

  1. var MyComponent = React.createClass({
  2. ...
  3. });
  4. module.exports = MyComponent;

ES6
在ES6里,通常用export default来实现相同的功能:

  1. export default class MyComponent extends Component{
  2. ...
  3. }

3.在初始化state上的不同

ES5

  1. var Video = React.createClass({
  2. getInitialState: function() {
  3. return {
  4. loopsRemaining: this.props.maxLoops,
  5. };
  6. },
  7. })

ES6
ES6下,有两种写法:

  1. class Video extends React.Component {
  2. state = {
  3. loopsRemaining: this.props.maxLoops,
  4. }
  5. }

不过我们推荐更易理解的在构造函数中初始化(这样你还可以根据需要做一些计算):

  1. class Video extends React.Component {
  2. constructor(props){
  3. super(props);
  4. this.state = {
  5. loopsRemaining: this.props.maxLoops,
  6. };
  7. }
  8. }

4.在方法作为回调上的不同

在开发工作中,经常会使用到回调,如按钮的单击回调等,这也是在很多编程语言中都会经常出现的情况。ES6与ES5在使用回调方面是有区别的。

ES5

  1. var PostInfo = React.createClass({
  2. handleOptionsButtonClick: function(e) {
  3. // Here, 'this' refers to the component instance.
  4. this.setState({showOptionsModal: true});
  5. },
  6. render: function(){
  7. return (
  8. <TouchableHighlight onPress={this.handleOptionsButtonClick}>
  9. <Text>{this.props.label}</Text>
  10. </TouchableHighlight>
  11. )
  12. },
  13. });

在ES5中,React.createClass会把所有的方法都bind一遍,这样可以提交到任意的地方作为回调函数,而this不会变化。但官方现在逐步认为这反而是不标准、不易理解的。

在ES6下,你需要通过bind来绑定this引用,或者使用箭头函数(它会绑定当前scope的this引用):

ES6

  1. class PostInfo extends React.Component{
  2. handleOptionsButtonClick(e){
  3. this.setState({showOptionsModal: true});
  4. }
  5. render(){
  6. return (
  7. <TouchableHighlight
  8. onPress={this.handleOptionsButtonClick.bind(this)}
  9. //onPress={e=>this.handleOptionsButtonClick(e)}//这种方式和上面的效果是一样的
  10. >
  11. <Text>{this.props.label}</Text>
  12. </TouchableHighlight>
  13. )
  14. },·
  15. }

React Native的语法之ES5和ES6的更多相关文章

  1. React Native之React速学教程(下)

    概述 本篇为<React Native之React速学教程>的最后一篇.本篇将带着大家一起认识ES6,学习在开发中常用的一些ES6的新特性,以及ES6与ES5的区别,解决大家在学习Reac ...

  2. React Native入门——IDE及其它相关基础技术

    关于React Native的开发,当中一个问题是缺少好用的IDE,有些人说不就是JS么,搞一个记事本也就写了,那样尽管牛逼,但事实上还是非常头大的,有一款好的IDE还是能提升开发效率的,这里对几个还 ...

  3. React Native之ES5/ES6语法差异对照表

    很多React/React Native的初学者都被ES6的问题迷惑:各路大神都建议我们直接学习ES6的语法(class Foo extends React.Component),然而网上搜到的很多教 ...

  4. React/React Native 的ES5 ES6写法对照表

    //es6与es5的区别很多React/React Native的初学者都被ES6的问题迷惑:各路大神都建议我们直接学习ES6的语法(class Foo extends React.Component ...

  5. React/React Native 的ES5 ES6写法对照表-b

    很多React/React Native的初学者都被ES6的问题迷惑:各路大神都建议我们直接学习ES6的语法(class Foo extends React.Component),然而网上搜到的很多教 ...

  6. 【转】React Native中ES5 ES6写法对照

    很多React Native的初学者都被ES6的问题迷惑:各路大神都建议我们直接学习ES6的语法(class Foo extends React.Component),然而网上搜到的很多教程和例子都是 ...

  7. React,React Native中的es5和es6写法对照

    es6用在React中的写法总结: 在es6还没有完全支持到浏览器的阶段里,已经有很多技术人员开始用es6的写法来超前编程了,因为有转义es6语法的工具帮助下,大家才可大量使用.解析看看es6写法用在 ...

  8. React Native 的ES5 ES6写法对照表

    模块 引用 在ES5里,如果使用CommonJS标准,引入React包基本通过require进行,代码类似这样: //ES5 var React = require("react" ...

  9. react native 中es6语法解析

    react native是直接使用es6来编写代码,许多新语法能提高我们的工作效率 解构赋值 var { StyleSheet, Text, View } = React; 这句代码是ES6 中新增的 ...

随机推荐

  1. P3613 睡觉困难综合征(LCT + 位运算)

    题意 NOI2014 起床困难综合症 放在树上,加上单点修改与链上查询. 题解 类似于原题,我们只需要求出 \(0\) 和 \(2^{k - 1} - 1\) 走过这条链会变成什么值,就能确定每一位为 ...

  2. Spring MVC工作原理 及注解说明

    SpringMVC框架介绍 1) spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面. Spring 框架提供了构建 Web 应用程序的全功 ...

  3. kvm 虚拟机XML文件

    <domain type='kvm' id='29'> //domain 是一个所有虚拟机都需要的根元素,它有两个属性, //type定义使用哪个虚拟机管理程序,值可以是:xen.kvm. ...

  4. dns配置文件

    /etc/resolv.conf 该文件是DNS域名解析的配置文件,它的格式很简单,每行以一个关键字开头,后接配置参数. resolv.conf的关键字主要有四个,分别是: nameserver   ...

  5. [2017-7-28]Android Learning Day7

    View动画效果 透明动画效果 旋转动画效果 移动动画效果 缩放动画效果 混合动画效果 1.透明动画效果(AlphaAnimation) 有两种方法 第一种在活动中设置,不需要xml文件 public ...

  6. linux下的标准输出和错误输出重定向

    如果想要将对应信息输出到某个文件中,就用对应的数字加上重定向符号“>”,会将这些信息,重新定向到指定的文件中,即可.简单说明:系统默认的stdin,stdout,stderr,都是送往屏幕,所以 ...

  7. javascript柯里化及组合函数~

    大家是不是看我上篇博文有点蒙.用的的curry和compose是什么鬼,怎么那么神奇.上篇博文也是主要用到了这两个函数.那今天我们来聊一下curry和compose,这两个东西是函数式编程很重要的东西 ...

  8. Nginx宣布正式支持gRPC,附示例代码

    原创 2018-03-20 薛命灯 聊聊架构 作者|Owen Garrett编辑|薛命灯 NGINX 官方博客正式宣布 NGINX 支持原生的 gPRC,现在就可以从代码仓库拉取快照版本.该特性将会被 ...

  9. js 判断字符串中是否包含某个字符串

    String对象的方法 方法一: indexOf()   (推荐) var str = "123"; console.log(str.indexOf("3") ...

  10. luogu4211 LCA

    题目链接 思路 我们换一种求\(dep[lca(i,j)]\)的方法. 将从根到\(i\)的路径上所有点的权值加\(1\),然后求从根节点到j路径上点的权值和.就是\(i\)和\(j\)的\(lca\ ...