//例1
function foo(x) {
return x + 10
}
foo('Hello!')
//例2
function main(params){
//fn1函数获取了一个数据
var object = fn1(params)
//fn2根据获数据,产生一个结果
var result = fn2(object)
return result
}
复制代码
例2很明显,这个过程很是的‘黑’,若是你想知道object包含什么数据的话,能够:javascript
被上述步骤折磨完以后,终于能真正的写点代码了,可是依旧得很是当心,由于这里还有另外一个函数:fn2java
在修改代码的时候,得保证result这个结果没有被影响,那么如何保证呢?react
很简单,重复上面的步骤,搞清楚result包含的数据,在测试的时候确保其数据跟原先的相同。 ...bash
动态类型一时爽,代码重构火葬场 知乎传送门:为何说“动态类型一时爽,代码重构火葬场”babel
是时候完全优化这个烦人的问题了angular2
其实问题的根源就是由于javascript太灵活了,在代码运行期间几乎能够作任何的修改,框架
没有东西能够在代码层面保证 某个变量,某个函数 跟预期的一致。函数
因此要加入类型系统来确保代码的可靠性,在后期维护的时候一样可以传达出有效的信息工具
Flow是个JavaScript的静态类型检查工具,由Facebook出品的开源码项目,问世只有两三年,是个至关年轻的项目。简单来讲,它是对比TypeScript语言的解决方式。学习
会有这类解决方案,原由是JavaScript是一种弱(动态)数据类型的语言,弱(动态)数据类型表明在代码中,变量或常量会自动依照赋值变动数据类型,并且类型种类也不多,这是直译式脚本语言的常见特性,但有多是优势也是很大的缺点。优势是容易学习与使用,缺点是像开发者常常会由于赋值或传值的类型错误,形成不如预期的结果。有些时候在使用框架或函数库时,若是没有仔细看文件,亦或是文件写得不清不楚,也容易形成误用的状况。
这个缺点在应用规模化时,会显得更加严重。咱们在团队开发协同时,通常都是经过统一的代码规范,来下降这个问题的发生,但JS语言自己
没法有效阻止这些问题。TypeScript这样的强(静态)类型的JavaScript超集语言就开始流行,用严格的角度,以JavaScript语言为基底,来从新打造另外一套具备强(静态)类型特性的语言,就如同Java或C#这些语言同样,这也是为何TypeScript称本身是企业级的开发JavaScript解决方案。
TypeScript天然有它的市场,但它有一些明显的问题:
因此许多现行的开源码函数库或框架,并不会直接使用TypeScript做为代码的语言,另外一方面由于TypeScript并不是是普及到必定程度的语言。 固然TypeScript也是个活跃的开源码项目,发展到如今也有一段时间,它的背后有微软公司的支持,全新打造过的Angular2框架中(由Google主导),也采用了TypeScript做为基础的开发语言。
如今,Flow提供了另外一个新的选项,它是一种强(静态)类型的辅助检查工具
。Flow的功能是让现有的JavaScript语法能够事先做类型的声明(定义),在开发过程当中进行自动检查
,固然在最后编译时,同样能够用babel工具来移除这些标记。
相较于TypeScript是另外从新制定一套语言,最后再通过编译为JavaScript代码来运行。Flow走的则是非强制与非侵入性的路线。
轻
且易学易用 它的学习曲线没有TypeScript来得高,虽然内容也不少,但半天学个大概,就能够渐进式地开始使用检查工具
不是新的程序语言或超集语言,因此它能够与各类现有的JavaScript代码兼容,若是你哪天不想用了,就去除掉标记就是回到原来的代码,没什么负担选择flow.js工具而不选择TypeScript强类型语言的缘由显而易见? flow.js对工程的侵入性很小,无需大量的额外工做就能使用起来
这种类型不符的状况在代码中很是容易发生,例如上面的例1:
function foo(x) {
return x + 10
}
foo('Hello!')
复制代码
x这个传参,咱们在函数声明时但愿它是个数字类型,但最后使用调用函数时则用了字符串类型。最后的结果会是什么吗? "Hello!10",这是由于加号(+)在JavaScript语言中,除了做为数字的加运算外,也能够看成字符串的链接运算。想固然这并非咱们想要的结果。
聪明如你应该会想要用类型来当传参的识别名,容易一眼看出传参要的是什么类型,像下面这样:
function foo(number) {
return number + 10
}
复制代码
利用Flow类型的定义方式,来解决这个小案例的问题,能够改写为像下面的代码:
// @flow
function foo(x: number): number {
return x + 10
}
foo('hi')
复制代码
当使用非数字类型的值做为传入值时,就会出现由Flow工具发出的警告消息,像下面这样:
[flow] Cannot call
foo
with'hi'
bound tox
because string 1 is incompatible with number 2. (a.getting-start.js:6:5)
若是是要容许多种类型也是很容易能够加标记的,假使这个函数可使用布尔与数字类型,但返回能够是数字或字符串,就像下面这样修改过:
// @flow
function foo(x: number | boolean): number | string {
if (typeof x === 'number') {
return x + 10
}
return 'x is boolean'
}
foo(1)
foo(true)
foo(null) // 这一行有类型错误消息
复制代码
在多人协同开发某个有规模的JavaScript应用时,这种类型的输出输入问题就会很常碰见。若是利用Flow工具的检查,能够避免掉许多没必要要的类型问题。
可能你会认为Flow工具只能运用在小型代码中,其实否则,Vue源码中大量使用flowjs中类型检测:
"javascript.validate.enable": false
4 . babel插件在编译时就会一并转换Flow标记
{
"plugins": [
"transform-flow-strip-types"
]
}
复制代码
Flow支持原始数据类型,以下面的列表:
// @flow
export type Test = {
titleOne?: string,
titleTwo: ?string
}
var a: Test = {titleOne:"3",titleTwo:4}
var b:string = ""
//any
export type NavigationGestureDirection = 'horizontal' | 'vertical';
type T = Array<string>
var x: T = []
x["Hi"] = 2 //有Flow警告
type TT = Array<Test>
var xx:TT = []
xx = [{titleOne: '1',
titleTwo: false}]
type MyObject = {
foo: number,
bar: boolean,
baz: string,
};
let val:MyObject = {foo:2,bar:false,baz:'444'};
var val1: MyObject = {foo:2,bar:false,baz:null};
var val2: MyObject = {foo:2,bar:false};
function method(val: MyObject):MyObject { return {foo:2,bar:false,baz:'2'}}
class Foo { constructor(val: MyObject) { /* ... */ } }
复制代码
若是你在React class里面使用了React.PropTypes规范,你能够对JSX上的attributes作静态类型检查:
var Hello = React.createClass ({
propTypes: {
name: React.PropTypes.string.isRequired
}
...
});
//<Hello/> //Flow就会发现 缺乏属性的错误
//<Hello name={42}/>//属性类型的错误
复制代码
import * as React from 'react';
type Props = {
foo: number,
bar?: string,
};
function MyComponent(props: Props) {
props.doesNotExist; // Error! You did not define a `doesNotExist` prop.
return <div>{props.bar}</div>;
}
<MyComponent foo={42} />
复制代码
更多关于支持React的细节 请移步 https://flow.org/en/docs/react/components/