用flow.js提高前端開發的體驗

在當心翼翼維護項目代碼的時候常常會看到這種代碼javascript

function main(){
   //fn1函數獲取了一個數據
   var object = fn1()
   //fn2根據獲數據,產生一個結果
   var result = fn2(object)

   return result
}

很明顯,這個過程很是的‘黑’,若是你想知道object包含什麼數據的話,能夠html

  1. 打印一下 console.log(object)前端

  2. 查看fn1的註釋,而且保佑它的註釋是正確,全面的java

  3. 或結合1,2,而後仔細查看fn1的源碼,但願它不是很複雜node

被上述步驟折磨完以後,終於能真正的寫點代碼了,可是依舊得很是當心,由於這裏還有另外一個函數:fn2。webpack

在修改代碼的時候,得保證result這個結果沒有被影響,那麼如何保證呢?git

很簡單,重複上面的步驟,搞清楚result包含的數據,在測試的時候確保其數據跟原先的相同。github

web

是時候完全優化這個煩人的問題了。npm

引入類型系統

其實問題的根源就是由於javascript太靈活了,在代碼運行期間幾乎能夠作任何的修改,

沒有東西能夠在代碼運行前就保證 某個變量,某個函數 跟預期的一致。

因此要加入類型系統來確保代碼的可靠性,在後期維護的時候一樣可以傳達出有效的信息。

facebook出品的flow.js 作的就是這種事情。

使用flow.js

git 倉庫:https://github.com/facebook/flow
flow 官方文檔:https://flowtype.org/docs/qui...

方便體驗,這裏有一個搭好的case集合

git clone git@github.com:JavascriptTips/flow-examples.git

基礎類型檢測

flow.js 中定義了的5種最簡單的類型,(warning:都是小寫),其中void對應js中的undefined

  • boolean

  • number

  • string

  • null

  • void

要想加入到javascript中,只須要在關鍵的地方聲明想要的類型。其它時間咱們的代碼仍是熟悉的javascript,代碼以下(flow-examples工程中也有對應js文件):

//flow-examples/src/primitives.js

//在文件的頭部加入,用註釋加入 `@flow` 聲明,這樣flow.js纔會檢查這個文件。
//@flow

//在聲明變量時,在變量名加入 `:[Type]` 來代表變量的類型,其它類型同理。
//這個語法很是像flash的ActionScript,咦?好像暴露了什麼。
var num:number = 1;
var str:string = 'a';

//固然,也能夠不加類型,這樣就跟原來的js同樣了。
var variable = 'zz';

複雜類型檢測

主要有:

  • Object

  • Array

  • 函數

  • 自定義Class

這幾個類型比較複雜,並且能夠相互嵌套。在flow.js中這幾種類型有很是多的檢查語法,在這裏簡單的展現幾項,具體見代碼代碼和官方文檔。

對象:Object
//flow-examples/src/object.js
//@flow

//Object大寫的O
var o:Object = {
  hello:'h'
};

//聲明瞭Object的key
var o2:{key:string} = {
  key:'z233'
};
數組:Array
//flow-examples/src/array.js
//@flow


//基於基本相似的數組,數組內都是相同類型
var numberArr:number[] = [12,3,4,5,2];
//另外一個寫法
var numberAr2r:Array<number> = [12,3,2,3];

var stringArr:string[] = ['12','a','cc'];
var booleanArr:boolean[] = [true,true,false];
var nullArr:null[] = [null,null,null];
var voidArr:void[] = [ , , undefined,void(0)];


//數組內包含各個不一樣的類型數據
//第4個原素沒有聲明,則能夠是任意類型
var arr:[number,string,boolean] = [1,'a',true,function(){},];
函數

函數比較特殊,由於函數的核心在於參數和返回值,函數做文類型自己並無做用。

//flow-examples/src/function.js
//@flow

/**
 * 聲明帶類型的函數
 * 這裏是聲明一個函數fn,規定了本身須要的參數類型和返回值類型。
 */
function fn(arg:number,arg2:string):Object{
  return {
    arg,
    arg2
  }
}
//同理,ES2015箭頭函數的寫法
var fn2 = (arg:number,arg2:string):Object => {
  return {
    arg,
    arg2
  }
}

/**
 * 這裏是聲明變量fn2,規定了它所需的函數的特徵:
 * 參數: (arg:string,arg2:number)
 * 返回值:Object
 */
var fn3:(arg:string,arg2:number)=>Object = function(){
  return {}
}

/**
 * 對比下面這種寫法,
 * 二者的聲明的地方不同,形成的意義也不一樣。
 */
var fn4 = function(arg:string,arg2:Object):number{
  return 1;
}
自定義的class

聲明一個自定義類,而後用法如同基本類型

//flow-examples/src/class.js
//@flow

class MyClass{
  name:string;
  constructor(n){
    this.name = n;
  }
}

var myClass : MyClass = new MyClass('abc');

引入flow.js

能夠看到加入flow.js語法後,正常的js引擎確定是不能跑的。

這時就要藉助萬能的babel編譯這些js。

1.若是是正經的帶webpack + babel 的前端項目,能夠無縫集成,加入babel插件便可:

babel-plugin-transform-flow-strip-types

2.若是隻是跑一下測試這些js,能夠直接在flow-examples工程中,以下:

npm run fnode src/object.js

其它跑起來的方法,能夠在官方文檔查看

結論

這裏只是介紹了flow.js一部分的特性,在引入flow.js以後,js只須要很小的改動就能獲得加強,在關鍵的地方確保邏輯的準確性。

更進一步,再結合js的函數式編程特性,以類型和函數驅動開發,感受很cool.

一點微小的疑問

這裏2個小問題,

爲何是flow.js 而不是其它編譯到js的強類型語言,如TypeScript ?

答:我很是喜歡js的靈活性,它爲編程帶來極大便捷。並且flow.js對工程的侵入性很小,無需大量的額外工做就能使用起來。

爲何不增強註釋,完善註釋,而是再加入一個工具?答:由於寫註釋很煩,而且有無註釋不會影響代碼執行。flow.js則是一種基本保障,確保檢查無誤才能運行。

相關文章
相關標籤/搜索