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 构成:
vuejs源码讲解从flow.js开始——一个JavaScript 静态类型检测工具_第1张图片

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[]``?ArrayArray不等效。要达到Array效果需要添加括号:

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 做了简单介绍

官网查看更多操作

相关链接:
vue源码讲解系列之一------声明式渲染new Vue()过程发生了什么

vue源码讲解系列之二------ render()函数、VNode虚拟节点的实现

你可能感兴趣的:(vue)