vuejs源碼講解從flow.js開始——一個JavaScript 靜態類型檢測工具

從今天開始我要不間斷地在分享 JavaScript 進階系列、web 性能等系列的文章的同時分享一些 Vuejs 的閱讀源碼理解。希望和廣大程序員們一起進步,一起學習,一起分享。

1.從 flow.js 開始

官網上介紹 flow 是 JavaScript 靜態類型檢測工具,能夠更規範、高效地編寫 JavaScript 代碼。
首先看個栗子:

// @flow
function square(n: number): number {
  return n * n;
}

square("2"); // Error!

從上面栗子中我們大概知道了 flowjs 的使用以及作用,在這裏使用number規定了函數傳參類型爲數字否則報錯。和 Ts 很像。

爲什麼先講 flowjs?

在 Vue 文件夾目錄下可以看到不少這樣的代碼,這些就是由 flow 構成:
在這裏插入圖片描述

flow 較之 typescript 的優勢
更輕巧、即拿即用、適合在代碼的各個地方無縫入侵。

安裝

npm 或 yarn 隨便選擇, flow 是輔助型工具,輔助開發過程中使用,所以安裝到 devDependency 下。

yarn add --dev flow-bin

安裝轉譯工具@babel/core@babel/cli,@babel/preset-flow,都是工具類都放 devDependency 下。

yarn add --dev @babel/core @babel/cli @babel/preset-flow

在項目根目錄創建一個.babelrc 文件。放入代碼:

{
  "presets": ["@babel/preset-flow"]
}

開始
初始化:

yarn run flow init

運行:

yarn run flow

flow 文件是以//@flow/*@flow*/註釋的 js 文件。例如:

// @flow
function foo(x: ?number): string {
  if (x) {
    return x;
  }
  return "default string";
}

這樣 flow 就會檢查這個文件,其他沒註釋的 js 文件會忽略檢測。但可以使用flow check --all來檢測所有 js 文件。

常見類型判斷
比如:

function concat(a, b) {
  return a + b;
}

這裏函數參數可以爲字符串也可以爲數字,因爲它們都可以使用+運算符操作。使用 flow 可以規定參數 a,b 只能是 string 或者 number 類型。
比如:

// @flow

// a,b僅支持string
function concat(a: string, b: string) {
  return a + b;
}
// a,b僅支持number
function concat(a: number, b: number) {
  return a + b;
}
//如果既接收number也接收string,則使用`|`表示
function concat(a: number | string, b: number | string) {
  return a + b;
}
//判斷多個參數
function method(x: number, y: string, z: boolean) {
  /*...*/
}
method(3.14, "hello", true);

// 如果是大寫,則爲接收構造函數
function method(x: Number, y: String, z: Boolean) {
  /* ...*/
}
method(new Number(42), new String("world"), new Boolean(false));

// 可以判斷null和undefined類型。但是undefined使用`viod`判斷.
function acceptsNull(value: null) {
  /* ... */
}
function acceptsUndefined(value: void) {
  /* ... */
}
acceptsNull(null); // Works!
acceptsNull(undefined); // Error!
acceptsUndefined(null); // Error!
acceptsUndefined(undefined); // Works!
// 可選類型,一種是`?string``?number`問號加在值前面,一種是`propertyName?`問號加在屬性/值後面。
//例如可選值,值可以爲字符串、空、null、undefined
function acceptsMaybeString(value: ?string) {
  // ...
}
acceptsMaybeString("bar"); // Works!
acceptsMaybeString(undefined); // Works!
acceptsMaybeString(null); // Works!
acceptsMaybeString(); // Works!

// 問號加在參數後面
function acceptsOptionalString(value?: string) {
  // ...
}
acceptsOptionalString("bar"); // Works!
acceptsOptionalString(undefined); // Works!
acceptsOptionalString(null); // Error!
acceptsOptionalString(); // Works!

//可選屬性,例如foo值可以爲字符串、undefined和空對象,但不能爲null。
function acceptsObject(value: { foo?: string }) {
  // ...
}
acceptsObject({ foo: "bar" }); // Works!
acceptsObject({ foo: undefined }); // Works!
acceptsObject({ foo: null }); // Error!
acceptsObject({}); // Works!

由上面可以看出?加在***前面則值可以爲 null,?加在***後面則值不可以爲 null。

數組類型判斷

let arr1: Array<boolean> = [true, false, true];
let arr2: Array<string> = ["A", "B", "C"];
let arr3: Array<mixed> = [1, true, "three"];
//簡寫:
let arr1: boolean[] = [true, false, true];
let arr2: string[] = ["A", "B", "C"];
let arr3: mixed[] = [1, true, "three"];

?Type[]``?Array<T>Array<?T>不等效。要達到Array<?T>效果需要添加括號:

let arr1: (?number)[] = null; // Error!
let arr2: (?number)[] = [1, 2]; // Works!
let arr3: (?number)[] = [null]; // Works!

函數類型判斷
對函數的參數和返回值約定類型,例如:
a,b 值爲 string 類型,返回值爲 string

function concat(a: string, b: string): string {
  return a + b;
}
//箭頭函數
let method = (str: string, bool?: boolean, ...nums: Array<number>): void => {
  return str;
};

以上對 flowjs 做了簡單介紹

官網查看更多操作

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章