<font id="zqva1"></font>
<rt id="zqva1"></rt>
  • <tt id="zqva1"></tt>
    <cite id="zqva1"></cite>

    <cite id="zqva1"><noscript id="zqva1"></noscript></cite>
      <rp id="zqva1"><meter id="zqva1"></meter></rp>

        <cite id="zqva1"></cite>
          <b id="zqva1"></b>
          <rp id="zqva1"></rp>
          <cite id="zqva1"></cite>

          <rt id="zqva1"></rt>

        1. <rp id="zqva1"></rp>

          Babel中的stage-0,stage-1,stage-2以及stage-3的作用(轉)

          時間:?2017-11-28閱讀:?2119標簽:?babel

          大家知道,將ES6代碼編譯為ES5時,我們常用到Babel這個編譯工具。大家參考一些網上的文章或者官方文檔,里面常會建議大家在.babelrc中輸入如下代碼: 

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

          我們現在來說明下這個配置文件是什么意思。首先,這個配置文件是針對babel 6的。Babel 6做了一系列模塊化,不像Babel 5一樣把所有的內容都加載。比如需要編譯ES6,我們需要設置presets為"es2015",也就是預先加載es6編譯的相關模塊,如果需要編譯jsx,需要預先加載"react"這個模塊。那問題來了,這個"stage-0"又代表什么呢? 有了"react-0",是否又有諸如"stage-1", "stage-2"等等呢?


          事實上, ”stage-0"是對ES7一些提案的支持,Babel通過插件的方式引入,讓Babel可以編譯ES7代碼。當然由于ES7沒有定下來,所以這些功能隨時肯能被廢棄掉的。現在我們來一一分析里面都有什么。

           

          1. 法力無邊的stage-0

          為什么說“stage-0” 法力無邊呢,因為它包含stage-1, stage-2以及stage-3的所有功能,同時還另外支持如下兩個功能插件:

          transform-do-expressionstransform-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'

          如果想更屌點,還可以寫出更牛逼的代碼: 

          const { map, filter } = Array.prototype;
          
          let sslUrls = document.querySelectorAll('a')
                          ::map(node => node.href)
                          ::filter(href => href.substring(0, 5) === 'https');
          console.log(sslUrls);


          2. 包羅萬象的stage-1

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

          • transform-class-constructor-call (Deprecated)
          • transform-class-properties
          • transform-decorators – disabled pending proposal update
          •  

             

            3.深藏不露的stage-2

            為什么說stage-2深藏不露呢,因為它很低調,低調到你可以忽略它,但事實上,它很有內涵的。它除了覆蓋stage-3的所有功能,還支持如下兩個插件:

            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'  // 增加新的參數
            );
            
            // 看到沒? 我們修改了4行代碼。。啊啊。修改了4行代碼。

            修改了4行代碼,嗯嗯嗯。。追求高效的程序猿想想了,以后如果有更多參數了,我是不是要改等多行,得想想,代碼改的越少越好,于是有了下面的改動。。

            
            // 我們來重新定義一下函數
            function clownPuppiesEverywhere(
              param1,
              param2, // 注意這里,我們加了一個逗號喲
            ) { /* ... */ }
            
            clownPuppiesEverywhere(
              'foo',
              'bar', // 這里我們也加了一個逗號
            );
            
            // 現在函數需要三個參數,我們來修改下
            function clownPuppiesEverywhere(
              param1,
              param2,
            + param3, // 增加params3參數
            ) { /* ... */ }
            
            clownPuppiesEverywhere(
              'foo',
              'bar',
            + 'baz', // 增加第三個參數
            );
            
            // 叮叮當,我們只修改了兩行代碼就完成了,好開森

            說實話吧,這個功能讓人有點很無語。不過程序猿對干凈代碼的追求真的很讓人感動,還是值得鼓勵的。這個就是stage-2中"尾逗號函數”功能。哈哈哈哈。

            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.大放異彩的stage3

            為啥說stage3大放異彩呢?因為它支持大名鼎鼎的async和await, 這兩個哥們可是解決(Ajax)回調函數的終極解決方法呀!管你什么異步,我都可以用同步的思維來寫,ES7里面非常強悍的存在。總的來說,它包含如下兩個插件:

            transform-async-to-generator

            transform-async-to-generator主要用來支持ES7中的async和await, 我們可以寫出下面的代碼:

            const sleep = (timeout)=>{
                return new Promise( (resolve, reject)=>{
                    setTimeout(resolve, timeout)
                })
            }
            
            (async ()=>{
                console.time("async");
                await sleep(3000);
                console.timeEnd("async");
            })()

            再來一個實際點的例子

            const fetchUsers = (user)=>{
                return window.fetch(`https://api.douban.com/v2/user/${user}`).then( res=>res.json())
            }
            
            
            const getUser = async (user) =>{
                let users = await fetchUsers(user);
                console.log( users);
            }
            
            console.log( getUser("flyingzl"))

            提示: 由于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-0,state-1,stage-2以及stage-3的區別。在進行實際開發時,可以更具需要來設置對應的stage。如果省事懶得折騰,一般設置為stage-0即可。如果為了防止開發人員使用某些太新的功能,我們可以限制到某個特定的stage即可。如果有其他問題,歡迎大家留言 :-)。 更詳細的請參考https://babeljs.io/docs/plugins/preset-stage-0/

             

             

            吐血推薦

            1.站長廣告聯盟: 整理了目前主流的廣告聯盟平臺,如果你有流量,可以作為參考選擇適合你的平臺點擊進入...

            2.休閑娛樂: 直播/交友    優惠券領取   網頁游戲   H5游戲

            鏈接: http://www.modern-decoration.com.cn/article/detial/186

          babel環境安裝與編譯

          babel:將瀏覽器不支持的ES6語法轉為javascript,初始化package.json文件:描述當前項目信息,包括依賴等,創建配置文件,告訴babel用什么規則來編譯文件.babelrc

          babel polyfill 的一些理解

          為了支持業務中少量的es6+的高級特性,最近在研究了一下babel的墊片,現將此整理為文字,如下。簡單來講,babel解決語法層面的問題。用于將ES6+的高級語法轉為ES5。

          入門babel,我們需要了解些什么

          說實話,我從工作開始就一直在接觸babel,然而對于babel并沒有一個清晰的認識,只知道babel是用于編譯javascript,讓開發者能使用超前的ES6+語法進行開發。自己配置babel的時候,總是遇到很多困惑,下面我就以babel@7為例

          使用@babel/preset-typescript取代awesome-typescript-loader和ts-loader

          談@babel/preset-typescript的優越性之前,還是先說下awesome-typescript-loader方案是如何對TypeScript進行處理的。首先我們需要知道TypeScript是一個將TypeScript轉換為指定版本JS代碼的編譯器

          webpack中配置babel

          因為在webpack中,默認只能處理一部分es6的語法,一些更高級的es6和es7語法webpack不能處理,這時就需要第三方的loader即babel來幫助webpack來處理這些高級的語法

          不容錯過的 Babel7 知識

          對 Babel 的配置項的作用不那么了解,是否會影響日常開發呢?老實說,大多情況下沒有什么影響。不過呢,還是想更進一步了解下,于是最近認真閱讀了 Babel 的文檔,外加不斷編譯驗證

          如何實現一個 Babel Macros?

          可以發現實現一個 Babel macros 的過程與開發 Babel 插件的流程類似,都是對 AST 進行操作。babel-plugin-macro 只是提供一個在“外部”進行 AST 修改的方式,通過這種方式能夠靈活的對 Babel 編譯時進行拓展

          如何將ES6轉換成ES5?

          ECMAScript 6(ES6)的發展速度非常之快,但現代瀏覽器對ES6新特性支持度不高,所以要想在瀏覽器中直接使用ES6的新特性就得借助別的工具來實現。Babel是一個廣泛使用的轉碼器,babel可以將ES6代碼完美地轉換為ES5代碼

          前端中的編譯原理:從零打造一個實用的 Babel 插件

          說起編譯原理,可能我們腦海中首先浮現的就是 “編譯器” 這個詞匯。維基百科上對編譯器的定義是: 編譯器是一種計算機程序,它會將某種編程語言寫成的源代碼(原始語言)轉換成另一種編程語言(目標語言)

          Babel-loader,babel-core和babel-preset之間是什么關系

          `babel-loader` 是一個 npm 包,它使得 webpack 可以通過 babel 轉譯 JavaScript 代碼。babel 的功能在于「代碼轉譯」,具體一點,即將目標代碼轉譯為能夠符合期望語法規范的代碼。在轉譯的過程中

          fly63.com版權所有,內容以共享、參考、研究為目的,不存在任何商業目的。其版權屬原作者所有,如有侵權,請與小編聯系!情況屬實本人將予以刪除!

          文章投稿關于web前端網站點搜索站長推薦網站地圖站長QQ:522607023

          小程序專欄: 土味情話心理測試腦筋急轉彎幽默笑話段子句子語錄成語大全

          国产精品高清视频免费 - 视频 - 在线观看 - 影视资讯 - 唯爱网