UDN-企业互联网技术人气社区

板块导航

浏览  : 558
回复  : 2

[原生js] 类型签名在 JavaScript 中的探索

[复制链接]
小辫儿的头像 楼主
发表于 2017-1-7 14:59:52 | 显示全部楼层 |阅读模式
  简介

  类型签名轻轻诉说着函数最不可告人的秘密。短短一行,就能暴露函数的行为和目的。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未实现)
  • 生成文档

  简单的例子
  1. // Number -> Number -> Number
  2. function add(a,b){
  3.   return a + b;
  4. }
复制代码

  add 上方的一行注释描述了函数从入参到返回值的过程,即 add 函数接受两个数字返回数字

  • Number 代表数字类型
  • 最后一个 Number 代表函数返回值的类型 前面两个 Number 分别代表函数的第一参数和第二个参数

  数组 函数

  js中有两个常用的类型,数组和函数,数组的类型可以写成 Array ,函数的类型可以写成 Function 。但这样的话我们从类型签名上获得的信息就很有限了,比如数组里面是什么?函数需要几个参?返回值是什么?

  数组的类型可以写成 [String] 代表数组内部是 String 的类型

  ps:其实数组可以看做容器 容器里面是什么还是要写上的,Promise也可以看做容器 比如类型可以写成 Promsie String
  1. // [String] -> [Number]
  2. // 求出每一项字符串的长度
  3. function everyLength(xs){
  4.   var r = [];
  5.   for (var i = 0; i < xs.length; i++) {
  6.     r.push(xs[i].length);
  7.   }
  8.   return r;
  9. }

  10. // [a] -> Number
  11. function length(xs){
  12.   return xs.length;
  13. }
复制代码

  • 所有的类型都是以大写开头,小写的 a 是类型变量 默认是代表任意类型(可以加约束)
  • everyLength 函数 输入一个字符串数组返回一个数字数组
  • length 输入一个数组返回一个数字

  函数可以写成 (String -> String) 即在原有的基础上加上一个括号 代表一个函数
  1. // (a -> b) -> [a] -> [b]
  2. function map(fn,xs){
  3.   var rs = [];
  4.   for(var i = 0;i < xs.length;i++){
  5.     rs.push(fn(xs[i]));
  6.   }
  7.   return rs;
  8. }
复制代码

  • a 和 b 是两个类型变量
  • map 函数: 第一个参数是一个函数(该函数接收一个类型 a 返回一个类型 b ) 第二个参数数组 数组内部的类型是 a (和前面函数 a 是相同的类型),返回值是数组其内部类型是 b (和前面函数的返回值保持一致)
  • 通过类型签名是不是可以获取到很多有效的信息 ^_^

  可选参数的函数

  我是不建议写带有可选参数,默认参数的函数的,这样会使函数产生多语意。更好的解决办法是写多个函数。如下,多选参数的函数就要写多个类型签名了
  1. // String -> Buffer
  2. // String -> String -> String
  3. function readFile(url,encoding){
  4.   if(encoding){
  5.     return fs.readFileSync(url,encoding);
  6.   }else{
  7.     return fs.readFileSync(url);
  8.   }
  9. }
复制代码

  该函数可以通过两种方式去调用

  • 传 Url 返回 Buffer
  • 传 URL 和 encoding 返回 String

  json 配置 和 无参 无返回值

  有很多时候我们写的json是没有具体类型的,可以通过 {必要的key:类型} 来进行描述 如下:
  1. //{url:String,fn:(String->())} -> ()
  2. function req(config){
  3.   // xx ....
  4.   fn(result);
  5. }
复制代码

  () 表示无返回值

  对象方法

  JavaScript 中的函数是可以使用this的 这种函数叫方法
  1. //Element ~> String -> ()
  2. function setText(text){
  3.   var div = $(this);
  4.   div.text(text);
  5. }
  6. $("[text-w]").each(setText);

  7. function Persion(){
  8.   // xx ....
  9. }

  10. // Persion ~> () -> String
  11. Persion.prototype.getName(){
  12.   return this.name;
  13. }
复制代码

  this 类型写在最前面 由于 this 不是一个参数 所以用 ~> 代替 -> 其它的保持不变

  总结

  以下是对类型的描述总结

  • Number 数字
  • String 字符串
  • [a] 数组
  • (a -> b -> c) 函数
  • () 无返回值 或者 无参数
  • Promise
  • {} json
  • this x ~> x

相关帖子

发表于 2017-1-7 15:00:21 来自手机 | 显示全部楼层
js框架越来越火了, 不过本人还是喜欢原生的好, 自己写类库, 自己来封装,用着方便。。。。
使用道具 举报

回复

发表于 2017-1-7 16:23:39 | 显示全部楼层
js太强大了,好多工作前端都可以做了…
使用道具 举报

回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关于我们
联系我们
  • 电话:010-86393388
  • 邮件:udn@yonyou.com
  • 地址:北京市海淀区北清路68号
移动客户端下载
关注我们
  • 微信公众号:yonyouudn
  • 扫描右侧二维码关注我们
  • 专注企业互联网的技术社区
版权所有:用友网络科技股份有限公司82041 京ICP备05007539号-11 京公网网备安1101080209224 Powered by Discuz!
快速回复 返回列表 返回顶部