博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
vue源码系列2--Flow.js
阅读量:6795 次
发布时间:2019-06-26

本文共 4886 字,大约阅读时间需要 16 分钟。

认识 Flow

JavaScript 是动态类型语言,它的灵活性有目共睹,但是过于灵活的副作用是很容易就写出非常隐蔽的隐患代码,在编译期甚至看上去都不会报错,但在运行阶段就可能出现各种奇怪的 bug。

flow.js是 facebook 出品的 JavaScript 静态类型检查工具,flow.js的理念类似于typescript,但是他比typescript更轻,更容易迁移,因为我们只需要做出很小的改变就可以使用flow.js,而typescript却非如此,它就像一门新的语言。

所以Vue.js 在做 2.0 重构的时候,在 ES2015 的基础上,除了 ESLint 保证代码风格之外,也引入了 Flow 做静态类型检查。

Flow 的工作方式

通常类型检查分成 2 种方式:

  • 类型推断:通过变量的使用上下文来推断出变量类型,然后根据这些推断来检查类型。

  • 类型注释:事先注释好我们期待的类型,Flow 会基于这些注释来判断。

类型推断

function split(str) {      return str.split(' ')    }        split(11)        //这时候会报错,因为期待的是string类型复制代码

类型注释

类型注释和TypeScript大同小异,举个例子

function add(x: number, y: number): number {      return x + y    }        add('Hello', 11)        //此时报错,因为我们期待的是number    后面的:number 是指返回的也是number类型复制代码

对象类型:

function method(x: Number, y: String, z: Boolean) {      // ...    }        method(new Number(42), new String("world"), new Boolean(false));复制代码

Boolean

在Flow中,默认并不会转换类型,如果你需要转换类型请使用显示或隐式转换,例如:

function acceptsBoolean(value: boolean) {      // ...    }        acceptsBoolean(true);  // Works!    acceptsBoolean(false); // Works!    acceptsBoolean("foo"); // Error!    acceptsBoolean(Boolean("foo")); // Works!    acceptsBoolean(!!("foo")); // Works!复制代码

Number

function acceptsNumber(value: number) {      // ...    }        acceptsNumber(42);       // Works!    acceptsNumber(3.14);     // Works!    acceptsNumber(NaN);      // Works!    acceptsNumber(Infinity); // Works!    acceptsNumber("foo");    // Error!复制代码

null和void

JavaScript兼有 null 和 undefined。Flow将这些视为单独的类型:null 和 void(void表示undefined类型)

function acceptsNull(value: null) {      /* ... */    }        function acceptsUndefined(value: void) {      /* ... */    }        acceptsNull(null);      // Works!    acceptsNull(undefined); // Error!    acceptsUndefined(null);      // Error!    acceptsUndefined(undefined); // Works!复制代码

也许类型

也许类型是用于可选值的地方,你可以通过在类型前添加一个问号(如 ?string 或者 ?number)来创建它们。 除了问号 ? 后跟着的类型,也许类型也可以是 null 或者 void 类型。

function acceptsMaybeString(value: ?string) {        // ...    }        acceptsMaybeString("bar");     // Works!    acceptsMaybeString(undefined); // Works!    acceptsMaybeString(null);      // Works!    acceptsMaybeString();          // Works!复制代码

可选的对象属性

对象类型可以具有可选属性,问号 ? 位于属性名称后面。

{ propertyName?: string }复制代码

除了它们的设定值类型之外,这些可选属性也可以被 void 完全省略。但是,他们不能 null。

function acceptsObject(value: { foo?: string }) {      // ...    }    acceptsObject({ foo: "bar" }); // Works!    acceptsObject({ foo: undefined }); // Works!    acceptsObject({ foo: null }); // Error!    acceptsObject({}); // Works!复制代码

可选的函数参数

函数可以具有可选参数,其中问号 ? 出现在参数名称后面。同样,该参数不能为 null。

function acceptsOptionalString(value?: string) {      // ...    }        acceptsOptionalString("bar");     // Works!    acceptsOptionalString(undefined); // Works!    acceptsOptionalString(null);      // Error!    acceptsOptionalString();          // Works!复制代码

文字类型

文字类型使用一个具体的值作为类型:

function foo(value: 2) {}        foo(2); // Work!    foo(3); // Error!    foo('2'); // Error!复制代码

可以使用这些类型的原始值:

  • 布尔: true 或 false
  • 数字:像 42 或 3.14
  • 字符串:像 "foo" 或 "bar"
function getColor(name: "success" | "warning" | "danger") {      switch (name) {        case "success" : return "green";        case "warning" : return "yellow";        case "danger"  : return "red";      }    }        getColor("success"); // Works!    getColor("danger");  // Works!    // $ExpectError    getColor("error");   // Error!复制代码

混合类型 mixed

有时候我们并不能确定需要的值到底是哪种类型,这时候我们可以使用混合类型来表示,但在使用该值之前,我们需要判断该值到底是哪种类型,否则会引起错误:

function stringify(value: mixed) {      // $ExpectError      return "" + value; // Error!    }        stringify("foo");复制代码
function stringify(value: mixed) {      if (typeof value === 'string') {        return "" + value; // Works!      } else {        return "";      }    }    stringify("foo");复制代码

任意类型 any

如果你想要一种方法来选择不使用类型检查器,any 是做到这一点的方法。

使用any是完全不安全的,应尽可能避免。

例如,下面的代码不会报告任何错误:

function add(one: any, two: any): number {      return one + two;    }        add(1, 2);     // Works.    add("1", "2"); // Works.    add({}, []);   // Works.复制代码

接口类型 interface

以使用 interface 以声明期望的类的结构:

interface Serializable {      serialize(): string;    }        class Foo {      serialize() { return '[Foo]'; }    }        class Bar {      serialize() { return '[Bar]'; }    }        const foo: Serializable = new Foo(); // Works!    const bar: Serializable = new Bar(); // Works!复制代码

你也可以使用 implements 告诉Flow,希望类匹配一个接口。这可以防止编辑类时发生不兼容的更改。

interface Serializable {      serialize(): string;    }        class Foo implements Serializable {      serialize() { return '[Foo]'; } // Works!    }        class Bar implements Serializable {      // $ExpectError      serialize() { return 42; } // Error!    }复制代码

数组类型 Array

要创建一个数组类型,可以使用 Array 类型,其中 Type 是数组中元素的类型

let arr: Array
= [1, 2, 3];复制代码

总结

Flow在开发过程中可以强制定义属性,在后期维护上可以大大节约维护成本。js作为弱类型语言确实再开发大型项目时,会出现奇奇怪怪的bug,所以加上静态校验是必不可少的。目前我司开发的项目,简单的基本上加上Flow,复杂重构的,已全部改为TypeScript来规避掉开发过程中声明不严谨的错误。

转载地址:http://xvggo.baihongyu.com/

你可能感兴趣的文章
jmeter tcp取样器使用方法
查看>>
linux中yum源
查看>>
企业生产MySQL主从同步配置
查看>>
Properties
查看>>
my97时间控件的使用
查看>>
nginx下配置多站点
查看>>
Adding a prefix header to an iOS project
查看>>
Perl 机选 双色球
查看>>
Linux操作系统基础解析之(七)——Bash(Shell)基础知识(5)
查看>>
LDAP认证vsftp方法
查看>>
通过RS232发送和接收短信(三)
查看>>
国内第一篇详细讲解hadoop2的automatic HA+Federation+Yarn的教程(1)
查看>>
在Centos下配置Rsync服务器
查看>>
异步超时后直接返回
查看>>
利用IT手段严防偷盗票房
查看>>
记《浪潮之巅》-第一版-2.蓝色巨人--IBM
查看>>
linux 系统安装后网卡配置,解决不能上网(重启后不能上网)(新手篇)
查看>>
有类路由与无类路由的区别
查看>>
企业网下の帧中继网络
查看>>
我的友情链接
查看>>