ES6语法入门

作者: 行者N | 来源:发表于2017-06-21 15:22 被阅读264次

    在React或者ReactNative学习和使用过程中,首先一个特点是看不太懂。因为它使用的是ES2015(ES6)的语法。特此从网上整理了一些必知必会的ES6知识点。大部分是引用的,后期自己有了心得也会更新这个文章。

    ES6

    ECMAScript 6.0(以下简称 ES6)是 JavaScript 语言的下一代标准,已经在2015年6月正式发布了。它的目标,是使得 JavaScript 语言可以用来编写复杂的大型应用程序,成为企业级开发语言。

    语法说明

    以说明ES6为主,后面可能会带上ES5的一些写法,主要是为了能够看懂别人写的东西,自己写的话,就写标准的ES6就好了。

    引用模块

    import React, { 
        Component,
        PropTypes,
    } from 'react';
    import {
        Image,
        Text
    } from 'react-native'
    
    //ES5 
    var React = require("react");
    var {
        Component,
        PropTypes
    } = React;  //引用React抽象组件
    

    导出类

    export default class MyComponent extends Component{
        ...
    }
    
    //ES5
    var MyComponent = React.createClass({
        ...
    });
    module.exports = MyComponent;
    

    定义组件

    class Photo extends React.Component {
        render() {
            return (
                <Image source={this.props.source} />
            );
        }
    }
    ////ES5
    var Photo = React.createClass({
        render: function() {
            return (
                <Image source={this.props.source} />
            );
        },
    });
    

    定义组件方法

    给组件定义方法不再用 名字: function()的写法,而是直接用名字(),在方法的最后也不能有逗号了

    class Photo extends React.Component {
        componentWillMount() {
    
        }
        render() {
            return (
                <Image source={this.props.source} />
            );
        }
    }
    

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

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

    class Video extends React.Component {
        static defaultProps = {
            autoPlay: false,
            maxLoops: 10,
        };  // 注意这里有分号
        static propTypes = {
            autoPlay: React.PropTypes.bool.isRequired,
            maxLoops: React.PropTypes.number.isRequired,
            posterFrameSrc: React.PropTypes.string.isRequired,
            videoSrc: React.PropTypes.string.isRequired,
        };  // 注意这里有分号
        render() {
            return (
                <View />
            );
        } // 注意这里既没有分号也没有逗号
    }
    
    //也可以这么写
    class Video extends React.Component {
        render() {
            return (
                <View />
            );
        }
    }
    Video.defaultProps = {
        autoPlay: false,
        maxLoops: 10,
    };
    Video.propTypes = {
        autoPlay: React.PropTypes.bool.isRequired,
        maxLoops: React.PropTypes.number.isRequired,
        posterFrameSrc: React.PropTypes.string.isRequired,
        videoSrc: React.PropTypes.string.isRequired,
    };
    

    因为static属性在IE11才可以继承,React可能会有些麻烦,ReactNative不存在这样的麻烦。

    初始化state

    class Video extends React.Component {
        state = {
            loopsRemaining: this.props.maxLoops,
        }
    }
    // 还可以写在构造函数中
    class Video extends React.Component {
        constructor(props){
            super(props);
            this.state = {
                loopsRemaining: this.props.maxLoops,
            };
        }
    }
    

    箭头函数

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

    ()=>1
    v=>v+1
    (a,b)=>a+b
    ()=>{
        alert("foo");
    }
    e=>{
        if (e == 0){
            return 0;
        }
        return 1000/e;
    }
    

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

    class PauseMenu extends React.Component{
        constructor(props){
            super(props);
            this._onAppPaused = this.onAppPaused.bind(this);
        }
        componentWillMount(){
            AppStateIOS.addEventListener('change', this._onAppPaused);
        }
        componentDidUnmount(){
            AppStateIOS.removeEventListener('change', this._onAppPaused);
        }
        onAppPaused(event){
        }
    }
    //或者这样也行
    class PauseMenu extends React.Component{
        componentWillMount(){
            AppStateIOS.addEventListener('change', this.onAppPaused);
        }
        componentDidUnmount(){
            AppStateIOS.removeEventListener('change', this.onAppPaused);
        }
        onAppPaused = (event) => {
            //把方法直接作为一个arrow function的属性来定义,初始化的时候就绑定好了this指针
        }
    }
    

    另外箭头函数还解决了javascript长期以来的this指代不明确的问题,如以下

    class Animal {
        constructor(){
            this.type = 'animal'
        }
        says(say){
            setTimeout(function(){
                console.log(this.type + ' says ' + say)
            }, 1000)
        }
    }
    
     var animal = new Animal()
     animal.says('hi')  //undefined says hi
    //上面的代码会报错,这是因为setTimeout中的this指向的是全局对象
    //传统解决方式如下
    //第一种是将this传给self,再用self来指代this
       says(say){
           var self = this;
           setTimeout(function(){
               console.log(self.type + ' says ' + say)
           }, 1000)
    //第二种方法是用bind(this),即
       says(say){
           setTimeout(function(){
               console.log(this.type + ' says ' + say)
           }.bind(this), 1000)
    
    // 下面也是正确的
    class Animal {
        constructor(){
            this.type = 'animal'
        }
        says(say){
            setTimeout( () => {
                console.log(this.type + ' says ' + say)
            }, 1000)
        }
    }
     var animal = new Animal()
     animal.says('hi')  //animal says hi
    

    当我们使用箭头函数时,函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。并不是因为箭头函数内部有绑定this的机制,实际原因是箭头函数根本没有自己的this,它的this是继承外面的,因此内部的this就是外层代码块的this。

    let, const

    这两个的用途与var类似,都是用来声明变量的。var 定义的是全局的变量,而let则实际上为JavaScript新增了块级作用域。用它所声明的变量,只在let命令所在的代码块内有效。const也用来声明变量,但是声明的是常量。一旦声明,常量的值就不能改变。当我们尝试去改变用const声明的常量时,浏览器就会报错。

    ///////////////////////////////var
    var name = 'zach'
    
    while (true) {
        var name = 'obama'
        console.log(name)  //obama
        break
    }
    
    console.log(name)  //obama
    ////////////////////////////////let
    let name = 'zach'
    
    while (true) {
        let name = 'obama'
        console.log(name)  //obama
        break
    }
    
    console.log(name)  //zach
    //////////////////////////////////const
    const PI = Math.PI
    const monent = require('moment')
    

    class 语法

    ES6提供了更接近传统语言的写法,这个java程序员很容易就看懂了。

    class Animal {
        constructor(){
            this.type = 'animal'
        }
        says(say){
            console.log(this.type + ' says ' + say)
        }
    }
    
    let animal = new Animal()
    animal.says('hello') //animal says hello
    
    class Cat extends Animal {
        constructor(){
            super()
            this.type = 'cat'
        }
    }
    
    let cat = new Cat()
    cat.says('hello') //cat says hello
    

    参考

    阮一峰 es6 入门
    React Native 中文社区
    30分钟掌握ES6/ES2015核心内容

    相关文章

      网友评论

        本文标题:ES6语法入门

        本文链接:https://www.haomeiwen.com/subject/bjyzqxtx.html