为什么80%的码农都做不了架构师?>>>
简介
类型签名轻轻诉说着函数最不可告人的秘密。短短一行,就能暴露函数的行为和目的。O(∩_∩)O~
作用
虽然js是动态类型的语言,但并不意味否定类型的存在,我们在写代码的时候还是要和Number,Boolean,String,Array等打交道,只不过没有在语言层面做类型检查。
- 简洁美观(对于我来说这一点就足够了)
- 降低阅读代码成本
- 有效节约沟通成本(附带装X技能) 以下是描述同一个函数的
- A:fs.readFile 函数有三个参数 第一个是字符串的文件路径,第二个是编码,第三个是回掉函数 回掉函数内部第一个代表错误,第二个代表文件内容(字符串) 无返回值
- B:fs.readFile :: String:路径 -> String:编码 -> (Error -> String) -> ()
- C:fs.readFile :: String -> String -> (Error -> String) -> ()
- 编译期间检查错误(js未实现)
- 生成文档
简单的例子
// Number -> Number -> Number
function add(a,b){
return a + b;
}
add
上方的一行注释描述了函数从入参到返回值的过程,即 add
函数接受两个数字返回数字
Number
代表数字类型- 最后一个
Number
代表函数返回值的类型 前面两个Number
分别代表函数的第一参数和第二个参数
数组 函数
js中有两个常用的类型,数组和函数,数组的类型可以写成Array
,函数的类型可以写成Function
。但这样的话我们从类型签名上获得的信息就很有限了,比如数组里面是什么?函数需要几个参?返回值是什么?
数组的类型可以写成 [String]
代表数组内部是String
的类型
ps:其实数组可以看做容器 容器里面是什么还是要写上的,Promise也可以看做容器 比如类型可以写成 Promsie String
// [String] -> [Number]
// 求出每一项字符串的长度
function everyLength(xs){
var r = [];
for (var i = 0; i < xs.length; i++) {
r.push(xs[i].length);
}
return r;
}
// [a] -> Number
function length(xs){
return xs.length;
}
- 所有的类型都是以大写开头,小写的
a
是类型变量 默认是代表任意类型(可以加约束) everyLength
函数 输入一个字符串数组返回一个数字数组length
输入一个数组返回一个数字
函数可以写成 (String -> String)
即在原有的基础上加上一个括号 代表一个函数
// (a -> b) -> [a] -> [b]
function map(fn,xs){
var rs = [];
for(var i = 0;i < xs.length;i++){
rs.push(fn(xs[i]));
}
return rs;
}
a
和b
是两个类型变量map
函数: 第一个参数是一个函数(该函数接收一个类型a
返回一个类型b
) 第二个参数数组 数组内部的类型是a
(和前面函数a
是相同的类型),返回值是数组其内部类型是b
(和前面函数的返回值保持一致)- 通过类型签名是不是可以获取到很多有效的信息 ^_^
可选参数的函数
我是不建议写带有可选参数,默认参数的函数的,这样会使函数产生多语意。更好的解决办法是写多个函数。如下,多选参数的函数就要写多个类型签名了
// String -> Buffer
// String -> String -> String
function readFile(url,encoding){
if(encoding){
return fs.readFileSync(url,encoding);
}else{
return fs.readFileSync(url);
}
}
该函数可以通过两种方式去调用
- 传
Url
返回Buffer
- 传
URL
和encoding
返回String
json 配置 和 无参 无返回值
有很多时候我们写的json是没有具体类型的,可以通过{必要的key:类型}
来进行描述 如下:
//{url:String,fn:(String->())} -> ()
function req(config){
// xx ....
fn(result);
}
()
表示无返回值
对象方法
javascript 中的函数是可以使用this的 这种函数叫方法
//Element ~> String -> ()
function setText(text){
var div = $(this);
div.text(text);
}
$("[text-w]").each(setText);
function Persion(){
// xx ....
}
// Persion ~> () -> String
Persion.prototype.getName(){
return this.name;
}
this
类型写在最前面 由于this
不是一个参数 所以用~>
代替->
其它的保持不变
总结
以下是对类型的描述总结
- Number 数字
- String 字符串
- [a] 数组
- (a -> b -> c) 函数
- () 无返回值 或者 无参数
- Promise
- {} json
- this x ~> x