认识Flow(一)
Flow 是 facebook 出品的 JavaScript 静态类型检查工具。Vue.js 的源码利用了 Flow 做了静态类型检查,所以了解 Flow 有助于我们阅读源码。
为什么用 Flow
JavaScript 是动态类型语言,它的灵活性有目共睹,但是过于灵活的副作用是很容易就写出非常隐蔽的隐患代码,在编译期甚至看上去都不会报错,但在运行阶段就可能出现各种奇怪的 bug。
类型检查是当前动态类型语言的发展趋势,所谓类型检查,就是在编译期尽早发现(由类型错误引起的)bug,又不影响代码运行(不需要运行时动态检查类型),使编写 JavaScript 具有和编写 Java 等强类型语言相近的体验。
项目越复杂就越需要通过工具的手段来保证项目的维护性和增强代码的可读性。 Vue.js 在做 2.0 重构的时候,在 ES2015 的基础上,除了 ESLint 保证代码风格之外,也引入了 Flow 做静态类型检查。之所以选择 Flow,主要是因为 Babel 和 ESLint 都有对应的 Flow 插件以支持语法,可以完全沿用现有的构建配置,非常小成本的改动就可以拥有静态类型检查的能力。
Flow 的工作方式
通常类型检查分成 2 种方式:
类型推断:通过变量的使用上下文来推断出变量类型,然后根据这些推断来检查类型。
类型注释:事先注释好我们期待的类型,Flow 会基于这些注释来判断。
类型推断
它不需要任何代码修改即可进行类型检查,最小化开发者的工作量。它不会强制你改变开发习惯,因为它会自动推断出变量的类型。这就是所谓的类型推断,Flow 最重要的特性之一。
通过一个简单例子说明一下:
/*@flow*/
function split(str) {
return str.split(' ')
}
split(11)
Flow 检查上述代码后会报错,因为函数 split
期待的参数是字符串,而我们输入了数字。
类型注释
如上所述,类型推断是 Flow 最有用的特性之一,不需要编写类型注释就能获取有用的反馈。但在某些特定的场景下,添加类型注释可以提供更好更明确的检查依据。
考虑如下代码:
/*@flow*/
function add(x, y){
return x + y
}
add('Hello', 11)
Flow 检查上述代码时检查不出任何错误,因为从语法层面考虑, +
既可以用在字符串上,也可以用在数字上,我们并没有明确指出 add()
的参数必须为数字。
在这种情况下,我们可以借助类型注释来指明期望的类型。类型注释是以冒号 :
开头,可以在函数参数,返回值,变量声明中使用。
如果我们在上段代码中添加类型注释,就会变成如下:
/*@flow*/
function add(x: number, y: number): number {
return x + y
}
add('Hello', 11)
现在 Flow 就能检查出错误,因为函数参数的期待类型为数字,而我们提供了字符串。
上面的例子是针对函数的类型注释。接下来我们来看看 Flow 能支持的一些常见的类型注释。
数组
/*@flow*/
var arr: Array<number> = [1, 2, 3]
arr.push('Hello')
数组类型注释的格式是 Array<T>
,T
表示数组中每项的数据类型。在上述代码中,arr 是每项均为数字的数组。如果我们给这个数组添加了一个字符串,Flow 能检查出错误。
类和对象
/*@flow*/
class Bar {
x: string; // x 是字符串
y: string | number; // y 可以是字符串或者数字
z: boolean;
constructor(x: string, y: string | number) {
this.x = x
this.y = y
this.z = false
}
}
var bar: Bar = new Bar('hello', 4)
var obj: { a: string, b: number, c: Array<string>, d: Bar } = {
a: 'hello',
b: 11,
c: ['hello', 'world'],
d: new Bar('hello', 3)
}
类的类型注释格式如上,可以对类自身的属性做类型检查,也可以对构造函数的参数做类型检查。这里需要注意的是,属性 y
的类型中间用 |
做间隔,表示 y
的类型即可以是字符串也可以是数字。
对象的注释类型类似于类,需要指定对象属性的类型。
Null
若想任意类型 T
可以为 null
或者 undefined
,只需类似如下写成 ?T
的格式即可。
/*@flow*/
var foo: ?string = null
此时,foo
可以为字符串,也可以为 null
。
目前我们只列举了 Flow 的一些常见的类型注释。如果想了解所有类型注释,请移步 Flow 的官方文档。
Flow 在 Vue.js 源码中的应用
有时候我们想引用第三方库,或者自定义一些类型,但 Flow 并不认识,因此检查的时候会报错。为了解决这类问题,Flow 提出了一个 libdef
的概念,可以用来识别这些第三方库或者是自定义类型,而 Vue.js 也利用了这一特性。
在 Vue.js 的主目录下有 .flowconfig
文件, 它是 Flow 的配置文件,感兴趣的同学可以看官方文档。这其中的 [libs]
部分用来描述包含指定库定义的目录,默认是名为 flow-typed
的目录。
这里 [libs]
配置的是 flow
,表示指定的库定义都在 flow
文件夹内。我们打开这个目录,会发现文件如下:
flow
├── compiler.js # 编译相关
├── component.js # 组件数据结构
├── global-api.js # Global API 结构
├── modules.js # 第三方库定义
├── options.js # 选项相关
├── ssr.js # 服务端渲染相关
├── vnode.js # 虚拟 node 相关
可以看到,Vue.js 有很多自定义类型的定义,在阅读源码的时候,如果遇到某个类型并想了解它完整的数据结构的时候,可以回来翻阅这些数据结构的定义。
总结
通过对 Flow 的认识,有助于我们阅读 Vue 的源码,并且这种静态类型检查的方式非常有利于大型项目源码的开发和维护。类似 Flow 的工具还有如 TypeScript,感兴趣的同学也可以自行去了解一下。
-----------------转自慕课网vue源码解析视频教程的内容-----------------
认识Flow(一)的更多相关文章
- Git 在团队中的最佳实践--如何正确使用Git Flow
我们已经从SVN 切换到Git很多年了,现在几乎所有的项目都在使用Github管理, 本篇文章讲一下为什么使用Git, 以及如何在团队中正确使用. Git的优点 Git的优点很多,但是这里只列出我认为 ...
- [LeetCode] Pacific Atlantic Water Flow 太平洋大西洋水流
Given an m x n matrix of non-negative integers representing the height of each unit cell in a contin ...
- BZOJ 4390: [Usaco2015 dec]Max Flow
4390: [Usaco2015 dec]Max Flow Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 177 Solved: 113[Submi ...
- ArcGIS制作放射状流向地图(Radial Flow Map)
流向地图火了,因为Facebook的那张著名的友邻图,抑或因为<数据可视化之美>中介绍飞行模式的航线图,总之,流向地图以它特殊的可视化形式,直观地展示事物之间的联系,尤其在展示网络流向.贸 ...
- SSIS Data Flow优化
一,数据流设计优化 数据流有两个特性:流和在内存缓冲区中处理数据,根据数据流的这两个特性,对数据流进行优化. 1,流,同时对数据进行提取,转换和加载操作 流,就是在source提取数据时,转换组件处理 ...
- Data Flow的Error Output
一,在Data Flow Task中,对于Error Row的处理通过Error Output Tab配置的. 1,操作失败的类型:Error(Conversion) 和 Truncation. 2, ...
- SSIS Data Flow 的 Execution Tree 和 Data Pipeline
一,Execution Tree 执行树是数据流组件(转换和适配器)基于同步关系所建立的逻辑分组,每一个分组都是一个执行树的开始和结束,也可以将执行树理解为一个缓冲区的开始和结束,即缓冲区的整个生命周 ...
- SSIS的 Data Flow 和 Control Flow
Control Flow 和 Data Flow,是SSIS Design中主要用到的两个Tab,理解这两个Tab的作用,对设计更高效的package十分重要. 一,Control Flow 在Con ...
- 前端必须了解的布局常识:普通流(normal flow)
目录 一.概述 二.块级元素和内联元素 常见的块级元素 BFC 常见的行内元素 IFC 三.哪些情况会脱离普通流 浮动 绝对定位 固定定位 display:none 四.总结 五.参考资料 一.概述 ...
- 财务报表 > 现金流表的直接法,间接法,Cash Flow from Operating Activites
经营活动现金流量 Cash Flow from Operating Activites 是指企业投资活动和筹资活动以外的所有的交易和事项产生的现金流量.它是企业现金的主要来源. 1. 直接法经营活动现 ...
随机推荐
- mysql 表结构操作
alter table name : alter table table1 to table2;add column : alter table 表名 add column 列名 varchar(); ...
- python部署到服务器
python部署到服务器 linux下的CentOS 7 自带python2.7.5, 使用 python --version 命令查看,因系统需要python2.7.5,因此我们并不卸载,另外安装p ...
- 最短路径:初涉Dijkstra算法
模板题目:https://www.luogu.com.cn/problem/P1339 我的代码: #include<cstdio> #include<cstring> #in ...
- H5网页布局+css代码美化
HTML5的结构化标签,对搜索引擎更友好 li 标签对不利于搜索引擎的收录,尽量少用 banner图片一般拥有版权,不需要搜索引擎收录,因此可以使用ul + li <samp></s ...
- opencv —— morphologyEx 开运算、闭运算、形态学梯度、顶帽、黑帽
开运算:先腐蚀后膨胀. 能够排除小亮点. 闭运算:先膨胀后腐蚀. 能够排除小黑点. 形态学梯度:膨胀图 — 腐蚀图. 对二值图像进行这一操作,可将图块的边缘突出出来,故可用来保留物体边缘轮廓. 顶帽: ...
- C语言程序设计(实验一)
实验项目:1.3.2,1.3.3,1.3.4,2.3.1,2.3.2 姓名:邹琼 实验地点:家 实验时间:2020年2月28日 一.实验目的与要求 1.实验目的 掌握DEVC++的安装方法,并实现 ...
- 在Windows7中的各种显示模式中桌面图标的尺寸
在Windows7中的各种显示模式中,图标的尺寸 window7 桌面icon设计尺寸大小桌面图标设计尺寸一般是多少超大图标:256X256大图标:128X128中图标:32X32平铺:32X32列表 ...
- 【Jmeter】jmeter提取response中的返回值,并保存到本地文件--BeanShell后置处理器
有个需求,需要在压测环境中,创建几十万的账号数据,然后再根据创建结果,查询到某些账号信息. 按照之前我的做法,直接Python调用API,然后再数据库查询: 但是近期所有开发人员的数据库访问权限被限制 ...
- 永久激活2018.3.5版phpstorm
下载文件JetbrainsIdesCrack-4.2.jar 文件在后面的附件 配置文件在访达的应用程序中找到phpstorm或者idea,右击,选择显示包含内容,点击显示进入Contents-> ...
- [译]C# 7系列,Part 10: Span<T> and universal memory management Span<T>和统一内存管理
原文:https://blogs.msdn.microsoft.com/mazhou/2018/03/25/c-7-series-part-10-spant-and-universal-memory- ...