從今天開始我要不間斷地在分享 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 做了簡單介紹