zoukankan      html  css  js  c++  java
  • Babel中的stage-0、stage-1、stage-2、stage-3

    大家知道,将ES6代码编译为ES5时,我们常用到Babel这个编译工具。大家参考一些网上的文章或者官方文档,里面常会建议大家在.babelrc中输入如下代码:

    {
        "presets": [
          "es2015",
          "react",
          "stage-0"
        ],
        "plugins": []
      }
    

    babel 总共分为三个阶段:解析,转换,生成。
    我们需要知道现在 babel 本身是不具备这种转化功能,提供这些转化功能的是一个个 plugin。所以我们没有配置任何 plugin 的时候,经过 Babel 输出的代码是没有改变的
    下面我们来了解一下Babel中的stage-0、stage-1、stage-2、stage-3ji及它们支持的一些插件

    1. 法力无边的stage-0

    为什么说“stage-0” 法力无边呢,因为它包含stage-1, stage-2以及stage-3的所有功能,同时还另外支持如下两个功能插件:

    transform-do-expressions
    transform-function-bind
    

    用过React的同学可能知道,jsx对条件表达式支持的不是太好,你不能很方便的使用if/else表达式,要么你使用三元表达,要么用函数。例如你不能写如下的代码:

    
    var App = React.createClass({
    
        render(){
            let { color } = this.props;
    
            return (
                <div className="parents">
                    {
                        if(color == 'blue') { 
                            <BlueComponent/>; 
                        }else if(color == 'red') { 
                            <RedComponent/>; 
                        }else { 
                            <GreenComponent/>; }
                        }
                    }
                </div>
            )
        }
    })
    

    在React中你只能写成这样:

    var App = React.createClass({
    
        render(){
            let { color } = this.props;
    
    
            const getColoredComponent = color => {
                if(color === 'blue') { return <BlueComponent/>; }
                if(color === 'red') { return <RedComponent/>; }
                if(color === 'green') { return <GreenComponent/>; }
            }
    
    
            return (
                <div className="parents">
                    { getColoredComponent(color) }
                </div>
            )
        }
    })
    

    transform-do-expressions 这个插件就是为了方便在 jsx写if/else表达式而提出的,我们可以重写下代码。

    var App = React.createClass({
    
        render(){
            let { color } = this.props;
    
            return (
                <div className="parents">
                    {do {
                        if(color == 'blue') { 
                            <BlueComponent/>; 
                        }else if(color == 'red') { 
                            <RedComponent/>; 
                        }else { 
                            <GreenComponent/>; }
                        }
                    }}
                </div>
            )
        }
    })
    

    再说说 transform-function-bind, 这个插件其实就是提供过 :: 这个操作符来方便快速切换上下文, 如下面的代码:

    obj::func
    // is equivalent to:
    func.bind(obj)
    
    obj::func(val)
    // is equivalent to:
    func.call(obj, val)
    
    ::obj.func(val)
    // is equivalent to:
    func.call(obj, val)
    
    // 再来一个复杂点的样例
    
    const box = {
      weight: 2,
      getWeight() { return this.weight; },
    };
    
    const { getWeight } = box;
    
    console.log(box.getWeight()); // prints '2'
    
    const bigBox = { weight: 10 };
    console.log(bigBox::getWeight()); // prints '10'
    
    // Can be chained:
    function add(val) { return this + val; }
    
    console.log(bigBox::getWeight()::add(5)); // prints '15'
    
    2. 包罗万象的stage-1

    stage-1除了包含stage-2和stage-3,还包含了下面4个插件:

    transform-class-constructor-call (Deprecated)
    transform-class-properties
    transform-decorators – disabled pending proposal update
    transform-export-extensions
    
    3. 深藏不露的stage-2

    为什么说 stage-2深藏不露呢,因为它很低调,低调到你可以忽略它,但事实上,它很有内涵的。它除了覆盖stage-3的所有功能,还支持如下两个插件:

    syntax-trailing-function-commas
    transform-object-reset-spread
    

    syntax-trailing-function-commas这个插件它不是对ES6功能的增加,而是为了增强代码的可读性和可修改性而提出的

    // 假设有如下的一个函数,它有两个参数
    function clownPuppiesEverywhere(
      param1,
      param2
    ) { /* ... */ }
    
    clownPuppiesEverywhere(
      'foo',
      'bar'
    );
    
    // 有一天,它需要变成3个参数,你需要这样修改
    function clownPuppiesEverywhere(
      param1,
    - param2
    + param2, // 这一行得加一个逗号
    + param3  // 增加参数param3
    ) { /* ... */ }
    
    clownPuppiesEverywhere(
      'foo',
    - 'bar'
    + 'bar', // 这里的修改为逗号
    + 'baz'  // 增加新的参数
    );
    

    // 我们来重新定义一下函数

    function clownPuppiesEverywhere(
      param1,
      param2, // 注意这里,我们加了一个逗号哟
    ) { /* ... */ }
    
    clownPuppiesEverywhere(
      'foo',
      'bar', // 这里我们也加了一个逗号
    );
    
    // 现在函数需要三个参数,我们来修改下
    function clownPuppiesEverywhere(
      param1,
      param2,
    + param3, // 增加params3参数
    ) { /* ... */ }
    

    stage-2中的syntax-trailing-function-commas就是有"尾逗号函数”功能

    transform-object-rest-spread
    再来说transform-object-rest-spread, 其实它是对 ES6中解构赋值的一个扩展,因为ES6只支持对数组的解构赋值,对对象是不支持的。如下面的代码所示:

    // 获取剩下的属性

    let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };
    console.log(x); // 1
    console.log(y); // 2
    console.log(z); // { a: 3, b: 4 }
    
    // 属性展开
    let n = { x, y, ...z };
    console.log(n); // { x: 1, y: 2, a: 3, b: 4 }
    
    4. 深藏不露的stage-3

    为啥说stage3大放异彩呢?因为它支持大名鼎鼎的async和await, 这两个哥们可是解决(Ajax)回调函数的终极解决方法呀!管你什么异步,我都可以用同步的思维来写,ES7里面非常强悍的存在。总的来说,它包含如下两个插件:

    transform-async-to-generator
    transform-exponentiation-operator
    

    transform-async-to-generator主要用来支持ES7中的async和await
    提示: 由于asycn和await是ES7里面的内容,现阶段不建议使用。为了顺利运行上面的代码,建议用webpack进行编译。
    transform-exponentiation-operator
    transform-exponentiation-operator这个插件算是一个语法糖,可以通过**这个符号来进行幂操作,想当于Math.pow(a,b)。如下面的样例

    
    // x ** y
    
    let squared = 2 ** 2;
    // 相当于: 2 * 2
    
    let cubed = 2 ** 3;
    // 相当于: 2 * 2 * 2
    
    
    // x **= y
    
    let a = 2;
    a **= 2;
    // 相当于: a = a * a;
    
    let b = 3;
    b **= 3;
    // 相当于: b = b * b * b;
    

    结语:在进行实际开发时,可以更具需要来设置对应的stage。如果省事懒得折腾,一般设置为stage-0即可。如果为了防止开发人员使用某些太新的功能,我们可以限制到某个特定的stage即可

  • 相关阅读:
    Linux 下判断磁盘是ssd还是hdd
    Ceph rgw COR测试
    nfs 挂载选项
    【Linux命令】dmsetup--device mapper 管理工具(更底层的管理工具)
    Device Mapper 存储介绍
    easyui combotree 默认 初始化时就选中
    EasyUI 添加tab页(iframe方式)(转)
    EasyUI DataGrid 配置参数
    EasyUI 后台接受DataGrid传来的参数
    (转)combogrid的代码实例
  • 原文地址:https://www.cnblogs.com/IT123/p/11327551.html
Copyright © 2011-2022 走看看