js高手进阶之路:underscore源码经典(一)

underscore 源码版本 1.8.2

起因

很多人向我推荐研究js,可以看看一些第三方js类库的源码,而源码之中最好解读也最简短的就是underscore,它也是我平常比较喜欢的一个库,因为它性价比高:体积小、能力强。打开一看,才1000多行,试着读了一下,确实很值得一看,所以对精彩部分做了一下整理。

闭包

整个函数在一个闭包中,避免污染全局变量。通过传入this(其实就是window对象)来改变函数的作用域。和jquery的自执行函数其实是异曲同工之妙。这种传入全局变量的方式一方面有利于代码阅读,另一方面方便压缩。
underscore写法:

jquery写法:

原型赋值

Array,Object,Function这些本质都是函数,获取函数原型属性prototype也是为了便于压缩。简单解释一下,如果代码中要扩展属性,可能这样写

而这种代码是不可压缩的,Object,prototype这些名字改了浏览器就不认得了。

但是上面的代码中创建了ObjProto之后,源生代码经过压缩之后,ObjProto就可能命名成a变量,那么原来的代码就压缩成

一个小建议就是凡事一段代码被使用两次以上都建议定义变量(函数),有利于修改和压缩代码。

格式

这种定义的方式省略了多余的var,格式也美观,让我想到了sublime中的一个插件alignment。

数据判断

判断是否为dom,dom的nodeType属性值为1。这里用!!强转为boolean值

判断是否为数组。由于Array.isArray函数是ECMAScript 5新增函数,所以为了兼容之前的版本,在原生判断函数不存在的情况下,后面重写了一个判断函数。用call函数来改变作用域可以避免当obj没有toString函数报错的情况。

判断是否为对象。先用typeof判断数据类型。函数也属于对象,但是由于typeof null也是object,所以用!!obj来区分这种情况。

判断是否为arguments,很简单,arguments有个特有属性callee。

NaN这个值有两个特点:1.它是一个数;2.不等于它自己。
‘+’放在变量前面一般作用是把后面的变量变成一个数,在这里已经判断为一个数仍加上’+’,是为了把var num = new Number()这种没有值的数字也归为NaN。

是不是以为如果是布尔值不是true就是false?还有第3中情况var b = new Boolean()。b也是布尔值。

用void 0来表示undefined,非常有意思的小技巧。不过常用方式还是if(xxx)来判断是不是undefined。

eq是underscore的一个内置函数,代码太长,不粘贴了。isEmpty调用了这个函数。整个思路由易到难,先用===比较简单数据,然后用toString来判断是否相等,最后用递归处理复杂的Array、Function和Object对象。

这里为了区分’+0’和’-0’,因为这两个数对计算结果是有影响的。

这里是对简单对象进行判断,分为两类,一类是StringRegExp,这种数据直接toString然后判断。另一类是NumberDateBoolean,通过转换成数字判断。

对于数组和对象只能用递归了,同时用aStack和bStack来暂存递归中的子对象。这里一个小技巧的就是先判断数组/属性的长度,如果不相等可以有效地减少递归。

打赏支持我写出更多好文章,谢谢!

打赏作者

打赏支持我写出更多好文章,谢谢!

任选一种支付方式

2 15 收藏 2 评论

关于作者:亚里士朱德

JSP工程师,多年大型国际项目开发经验。WEB前端工程师,擅长PC端以及移动端开发。js全栈工程师,熟悉node.js、mongoDB。开发者头条top10专栏作者慕课网签约讲师个人博客:yalishizhude.github.io 个人主页 · 我的文章 · 19 ·     

相关文章

可能感兴趣的话题



直接登录
最新评论
跳到底部
返回顶部