成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

前端進(jìn)階(5) - js 擴(kuò)展:靜態(tài)類型檢查(facebook flow)

孫淑建 / 661人閱讀

摘要:擴(kuò)展靜態(tài)類型檢查語(yǔ)言與系列等語(yǔ)言有一點(diǎn)很大的不同,就是語(yǔ)言是弱類型語(yǔ)言。但其實(shí)很多開(kāi)發(fā)人員還是比較喜歡用來(lái)開(kāi)發(fā)項(xiàng)目,所以開(kāi)發(fā)出來(lái)幫助語(yǔ)言擴(kuò)展靜態(tài)類型檢查功能,規(guī)避上面提到的問(wèn)題。

js 擴(kuò)展:靜態(tài)類型檢查(facebook flow)

js 語(yǔ)言與 java、C 系列等語(yǔ)言有一點(diǎn)很大的不同,就是 js 語(yǔ)言是弱類型語(yǔ)言。js 語(yǔ)言的這個(gè)特性可能讓大家覺(jué)得 js 很自由,沒(méi)有強(qiáng)制性的約束,但是當(dāng)遇到大型項(xiàng)目的時(shí)候,js 的這個(gè)特性就會(huì)變得比較麻煩,因?yàn)檫@會(huì)導(dǎo)致團(tuán)隊(duì)的代碼很不可控。這個(gè)原因也是促使 TypeScript 誕生的一個(gè)很重要的原因。

但其實(shí)很多開(kāi)發(fā)人員還是比較喜歡用 js 來(lái)開(kāi)發(fā)項(xiàng)目,所以 facebook 開(kāi)發(fā)出 flow 來(lái)幫助 js 語(yǔ)言擴(kuò)展靜態(tài)類型檢查功能,規(guī)避上面提到的問(wèn)題。

1. 代碼示例

flow 規(guī)定,在需要做 "flow 靜態(tài)類型檢查" 文件的開(kāi)頭加上 // @flow 這段注釋,讓工具識(shí)別這個(gè)文件需要做靜態(tài)類型檢查,否則就會(huì)當(dāng)作一般 js 文件對(duì)待,不做靜態(tài)類型檢查。

flow 靜態(tài)類型幾乎可以應(yīng)用到所有的 js 對(duì)象,包括 es6 擴(kuò)展的 class, module 等,也包括 jsx 語(yǔ)法。

以下是一些基礎(chǔ)的靜態(tài)類型舉例,更詳細(xì)的可以查看 Type Annotations | Flow.

1.1 基本類型

與 js 的基本數(shù)據(jù)類型類似,包括:

boolean: 對(duì)應(yīng) js 的 Boolean 類型

number: 對(duì)應(yīng) js 的 Number 類型

string: 對(duì)應(yīng) js 的 String 類型

null: 對(duì)應(yīng) js 的 null

void: 對(duì)應(yīng) js 的 undefined

正常的 js 代碼

let hello = "hello"; // 聲明一個(gè)變量

hello = 2 * 2; // 重新賦值

hello = []; // 重新賦值

加上 flow 靜態(tài)類型檢查擴(kuò)展的代碼

// @flow

let hello: string = "hello"; // 聲明一個(gè) string 類型的變量

hello = 2 * 2; // 報(bào)錯(cuò)

hello = []; // 報(bào)錯(cuò)

hello = "hi"; // 重新賦值
1.2 函數(shù)

正常的 js 代碼

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

plus(); // NaN
plus(1); // NaN
plus(1, 2); // 3
plus("hello"); // "helloundefined"
plus("hello", " hi"); // "hello hi"
plus({}, {}); // "[object Object][object Object]"

加上 flow 靜態(tài)類型檢查擴(kuò)展的代碼

// @flow

// 定義一個(gè) "兩個(gè)數(shù)字參數(shù),返回值也是數(shù)字" 的函數(shù)
function plus(a: number, b: number): number {
  return a + b;
}

plus(); // 報(bào)錯(cuò)
plus(1); // 報(bào)錯(cuò)
plus("hello"); // 報(bào)錯(cuò)
plus("hello", " hi"); // 報(bào)錯(cuò)
plus({}, {}); // 報(bào)錯(cuò)

plus(1, 2); // 3
1.3 可能(Maybe),可選(Optional),語(yǔ)義(Literal),混合(Mixed)

可能(Maybe)類型用一個(gè) ? 在類型前面表示,包含類型本身、nullundefined

// @flow

let hello: ?string; // 聲明一個(gè)數(shù)據(jù)類型可以是 string, null, undefined 的變量

hello = null; // 賦值
hello = undefined; // 重新賦值
hello = "hello"; // 重新賦值
hello = 1; // 報(bào)錯(cuò)
hello = true; // 報(bào)錯(cuò)

可選(Optional)類型一般用于對(duì)象屬性或者函數(shù)參數(shù),在名稱后面加一個(gè) ?,包含類型本身、undefined

// @flow

const obj: {hello? : string}; // 屬性 hello 可以是 string, undefined

obj = {}; // 賦值
obj = {hello: undefined}; // 重新賦值
obj = {hello: "hello"}; // 重新賦值
obj = {hello: null}; // 報(bào)錯(cuò)
obj = {hello: 1}; // 報(bào)錯(cuò)
obj = {hello: true}; // 報(bào)錯(cuò)

// 屬性 param 可以是 number, undefined
function method(param?: number) { /* ... */ }

method(); // 正常
method(undefined); // 正常
method(1.12); // 正常
method(null); // 報(bào)錯(cuò)
method("hello"); // 報(bào)錯(cuò)

語(yǔ)義(Literal)類型一般用于聲明某個(gè),某幾個(gè)特定的值(多個(gè)值用 | 分隔)

// @flow

let hello: "hello"; // 聲明一個(gè)只能賦值 "hello" 的變量

hello = "hello"; // 賦值
hello = "hi"; // 報(bào)錯(cuò)
hello = 12; // 報(bào)錯(cuò)
hello = undefined; // 報(bào)錯(cuò)
hello = null; // 報(bào)錯(cuò)

function method(param: 1 | "hi" | boolean): void { /* ... */ }

method(); // 報(bào)錯(cuò),缺少參數(shù)
method(1); // ok
method(1.2); // 報(bào)錯(cuò),類型不對(duì)
method("hi"); // ok
method("hello"); // 報(bào)錯(cuò),類型不對(duì)
method(true); // ok
method(false); // ok

混合(Mixed)類型是指任意數(shù)據(jù)類型

// @flow

let hello: mixed; // 聲明一個(gè) mixed 類型的變量

hello = "hello"; // 賦值
hello = "hi"; // 重新賦值
hello = 12; // 重新賦值
hello = undefined; // 重新賦值
hello = null; // 重新賦值
1.4 復(fù)合類型

數(shù)組

// @flow

let arr1: Array = [true, false, true]; // 聲明一個(gè)元素是 boolean 的數(shù)組
arr1 = [true, 1]; // 報(bào)錯(cuò),1 不是 boolean 值
arr1 = [""]; // 報(bào)錯(cuò),"" 不是 boolean 值

let arr2: Array = ["A", "B", "C"]; // 聲明一個(gè)元素是 string 的數(shù)組

let arr3: Array = [1, true, "three"] // 聲明一個(gè)元素是任意類型的數(shù)組
arr1 = [true, 1]; // 重新賦值 
arr1 = [""]; // 重新賦值

map

// @flow

// 聲明一個(gè) map 類型,其有一個(gè)名為 foo,類型 boolean 的子元素
let obj1: { foo: boolean } = { foo: true };
obj1 = {}; // 報(bào)錯(cuò),缺少 foo 這個(gè)屬性值
obj1 = {foo: 1}; // 報(bào)錯(cuò),屬性值 foo 的類型必須是 boolean
obj1 = {foo: false, bar: "hello"}; // 重新賦值

// 聲明一個(gè) map 類型,其有名為 foo, bar, baz,類型 number, boolean, string 的子元素
let obj2: {
  foo: number,
  bar: boolean,
  baz: string,
} = {
  foo: 1,
  bar: true,
  baz: "three",
};

更靜態(tài)類型可以查看 Type Annotations | Flow.

2. 使用工具

安裝

# 全局安裝
npm i -g flow-bin

# 本地安裝
npm i -D flow-bin

使用

flow init                       # 初始化項(xiàng)目

flow check path/to/dir          # 檢查這個(gè)目錄下所有的文件
flow check path/to/js/file      # 檢查指定文件
3. 配合 babel 一起使用

因?yàn)?flow 靜態(tài)類型只是對(duì) js 的擴(kuò)展,并不是 js 原生支持的,也不能直接運(yùn)行,所以,一般 flow 都是配合 babel 一起使用的,這樣就可以在程序運(yùn)行的時(shí)候進(jìn)行靜態(tài)類型檢查,達(dá)到我們想要的效果。

3.1 babel-preset-flow

安裝 babel-preset-flow,這樣 babel 在轉(zhuǎn)碼 js 文件時(shí)就能識(shí)別 flow 的語(yǔ)法。

npm i -D babel-preset-flow

.babelrc

{
  "presets": ["flow"]
}

源文件(flow)

// @flow

// 定義一個(gè) "兩個(gè)數(shù)字參數(shù),返回值也是數(shù)字" 的函數(shù)
function plus(a: number, b: number): number {
  return a + b;
}

plus(); // 報(bào)錯(cuò)
plus(1); // 報(bào)錯(cuò)
plus("hello"); // 報(bào)錯(cuò)
plus("hello", " hi"); // 報(bào)錯(cuò)
plus({}, {}); // 報(bào)錯(cuò)

plus(1, 2); // 3

轉(zhuǎn)碼后的文件

// 定義一個(gè) "兩個(gè)數(shù)字參數(shù),返回值也是數(shù)字" 的函數(shù)
function plus(a, b) {
  return a + b;
}

plus(); // 報(bào)錯(cuò)
plus(1); // 報(bào)錯(cuò)
plus("hello"); // 報(bào)錯(cuò)
plus("hello", " hi"); // 報(bào)錯(cuò)
plus({}, {}); // 報(bào)錯(cuò)

plus(1, 2); // 3
3.2 babel-plugin-flow-runtime

一般會(huì)在開(kāi)發(fā)環(huán)境下,使用 babel-plugin-flow-runtime 插件,這樣就可以在開(kāi)發(fā)的時(shí)候,實(shí)時(shí)檢查數(shù)據(jù)類型,就像原生的運(yùn)行 flow 靜態(tài)類型檢查一樣。(一般在產(chǎn)品環(huán)境不會(huì)使用這個(gè)功能,因?yàn)闀?huì)額外消耗 js 的性能)

npm i -D babel-plugin-flow-runtime flow-runtime

.babelrc

{
  "presets": ["flow"],
  "plugins": ["flow-runtime"]
}

源文件(flow)

// @flow

// 定義一個(gè) "兩個(gè)數(shù)字參數(shù),返回值也是數(shù)字" 的函數(shù)
function plus(a: number, b: number): number {
  return a + b;
}

plus(); // 報(bào)錯(cuò)
plus(1); // 報(bào)錯(cuò)
plus("hello"); // 報(bào)錯(cuò)
plus("hello", " hi"); // 報(bào)錯(cuò)
plus({}, {}); // 報(bào)錯(cuò)

plus(1, 2); // 3

轉(zhuǎn)碼后的文件

import t from "flow-runtime";


// 定義一個(gè) "兩個(gè)數(shù)字參數(shù),返回值也是數(shù)字" 的函數(shù)
function plus(a, b) {
  return a + b;
}

t.annotate(plus, t.function(t.param("a", t.number()), t.param("b", t.number()), t.return(t.number())));
plus(); // 報(bào)錯(cuò)
plus(1); // 報(bào)錯(cuò)
plus("hello"); // 報(bào)錯(cuò)
plus("hello", " hi"); // 報(bào)錯(cuò)
plus({}, {}); // 報(bào)錯(cuò)

plus(1, 2); // 3

這個(gè)時(shí)候,js 文件就會(huì)導(dǎo)入 flow-runtime 模塊,對(duì) plus 函數(shù)的參數(shù) a, b 和返回值進(jìn)行數(shù)據(jù)類型檢查,如果不符合數(shù)據(jù)定義,就會(huì)報(bào)錯(cuò)。

4. 后續(xù)

更多博客,查看 https://github.com/senntyou/blogs

作者:深予之 (@senntyou)

版權(quán)聲明:自由轉(zhuǎn)載-非商用-非衍生-保持署名(創(chuàng)意共享3.0許可證)

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/96960.html

相關(guān)文章

  • Flow, 一個(gè)新的Javascript靜態(tài)類型檢查

    摘要:原文鏈接翻譯于今天我們興奮的發(fā)布了的嘗鮮版,一個(gè)新的靜態(tài)類型檢查器。為添加了靜態(tài)類型檢查,以提高開(kāi)發(fā)效率和代碼質(zhì)量。這最終形成一個(gè)高度并行增量式的檢查架構(gòu),類似。知道縮小類型范圍時(shí)做動(dòng)態(tài)檢查的影響。 原文鏈接:https://code.facebook.com/posts/1505962329687926/flow-a-new-static-type-checker-for-java...

    liangzai_cool 評(píng)論0 收藏0
  • JS 靜態(tài)類型檢查工具 Flow

    摘要:本文主要介紹了解決作為弱類型語(yǔ)言沒(méi)有類型檢查痛點(diǎn)的靜態(tài)類型檢查工具,并且介紹了在中使用的方法,最后介紹了一些常用的語(yǔ)法。 本文主要介紹了解決JS作為弱類型語(yǔ)言沒(méi)有類型檢查痛點(diǎn)的靜態(tài)類型檢查工具 Flow ,并且介紹了在WebStorm中使用Flow的方法,最后介紹了一些常用的Flow語(yǔ)法。 1. 簡(jiǎn)介 JS作為一種腳本語(yǔ)言是沒(méi)有類型檢測(cè)的,這個(gè)特點(diǎn)有時(shí)候用著很方便,但在一個(gè)較大的項(xiàng)目中...

    CloudDeveloper 評(píng)論0 收藏0
  • 兩年React老兵的總結(jié) - 類型檢查

    摘要:系列引言最近準(zhǔn)備培訓(xùn)新人為了方便新人較快入手開(kāi)發(fā)并編寫高質(zhì)量的組件代碼我根據(jù)自己的實(shí)踐經(jīng)驗(yàn)對(duì)組件設(shè)計(jì)的相關(guān)實(shí)踐和規(guī)范整理了一些文檔將部分章節(jié)分享了出來(lái)由于經(jīng)驗(yàn)有限文章可能會(huì)有某些錯(cuò)誤希望大家指出互相交流由于篇幅太長(zhǎng)所以拆分為幾篇文章主要有以 系列引言 最近準(zhǔn)備培訓(xùn)新人, 為了方便新人較快入手 React 開(kāi)發(fā)并編寫高質(zhì)量的組件代碼, 我根據(jù)自己的實(shí)踐經(jīng)驗(yàn)對(duì)React 組件設(shè)計(jì)的相關(guān)實(shí)踐...

    scola666 評(píng)論0 收藏0
  • (譯 & 轉(zhuǎn)載) 2016 JavaScript 后起之秀

    摘要:在年成為最大贏家,贏得了實(shí)現(xiàn)的風(fēng)暴之戰(zhàn)。和他的競(jìng)爭(zhēng)者位列第二沒(méi)有前端開(kāi)發(fā)者可以忽視和它的生態(tài)系統(tǒng)。他的殺手級(jí)特性是探測(cè)功能,通過(guò)檢查任何用戶的功能,以直觀的方式讓開(kāi)發(fā)人員檢查所有端點(diǎn)。 2016 JavaScript 后起之秀 本文轉(zhuǎn)載自:眾成翻譯譯者:zxhycxq鏈接:http://www.zcfy.cc/article/2410原文:https://risingstars2016...

    darry 評(píng)論0 收藏0
  • flow從零開(kāi)始----安裝和配置

    摘要:資源官網(wǎng)安裝參考什么是是一個(gè)弱類型的解釋性語(yǔ)言,無(wú)法在編譯環(huán)節(jié)進(jìn)行靜態(tài)類型校驗(yàn),如果想也具備靜態(tài)類型檢查功能。那就得使用到由推出,官網(wǎng)是。 資源 官網(wǎng):https://flow.org/ 安裝:https://flow.org/en/docs/inst... 參考:https://www.01hai.com/note/av... https://www.jianshu.com/p...

    KoreyLee 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<