underscore源码分析系列-2-常见简单函数分析

前言

这一篇源码分析中,我们会试着去看underscore几个比较常见的函数

_.random

返回一个min 和 max之间的随机整数。如果你只传递一个参数,那么将返回0和这个参数之间的整数。取值范围是[min, max],注意是闭区间

1
2
3
4
5
6
7
_.random = function (min, max) {
if (max == null) {
max = min;
min = 0;
}
return min + Math.floor(Math.random() * (max - min + 1))
}

这个函数参数可以传进去两个或者一个,当为一个的时候,返回的是[0, max] 之间的一个整数,平实需要得到一个指定范围的数字的时候,比较常用。

_.noConflict

放弃Underscore 的控制变量”_”。返回Underscore 对象的引用。也就是为了防止冲突而做的处理。

1
2
3
4
5
6
7
// 注意在源码一开头有这句话
var previousUnderscore = root._;
_.noConflict = function() {
root._ = previousUnderscore;
return this;
}

代码非常简单,就是把原来的全局变量_给赋值回去,而将underscore的引用作为函数调用后的返回值,提供给调用方使用。这是一种非常经典的防止全局冲突的方法。

举个例子我们要写一个平实自己经常要用到的工具类,取的名字是$,当然假设之前,我们并不知道jQuery中也用了这个名字,那么在实际项目中为了防止自己写的这个工具库把全局的美元符号给污染掉,怎么办呢?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<script src="//cdn.bootcss.com/jquery/3.0.0/jquery.js"></script>
<script>
(function(win){
var prev$ = win.$,
$ = function () {
};
$.isUndefined = function (obj) {
return obj === void(0);
}
$.random = function (min, max) {
if (this.isUndefined(max)) {
max = min;
min = 0;
}
return min + Math.floor(Math.random() * (max - min + 1))
};
$.showMessage = function (msg) {
alert(msg)
};
$.noConflict = function () {
win.$ = prev$;
return this;
}
win.$ = $;
})(window);
$.showMessage('hello world'); // 弹出hello world
//自己写的$把jQuery中的$给覆盖掉了
var my$ = $.noConflict(); // 不执行这句 下面的$() 调用会没有反应
$(function(){
alert('hello world two'); // 弹出hello world two
})
</script>

_.noop

返回undefined,不论传递给它的是什么参数。 可以用作默认可选的回调参数。

1
_.noop = function(){};

underscore帮我们提供一个空函数,这个有啥用呢? 其实还真有用处,平实如果我们要初始化某个变量为空函数,方便后面再把这个变量对应的值替换掉。又或者甚至用作判断一个变量是否是undefined。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 1
if (a == _.noop()) {
alert('a 是 undefined')
}
// 2
var obj = {
showMsg: function () {},
showAge: function () {}
}
var obj = {
showMsg: _.noop,
showAge: _.noop
}

很显然这样可以有两个好处,

  1. 因为在ie低版本中undefined的值可能被改写,所以导致判断不准确。但是如果直接于_.noop()相比较就不会有这个问题
  2. 直接给浏览器省了创建两个空函数的麻烦

_.now

一个优化的方式来获得一个当前时间的整数时间戳。可用于实现定时/动画功能。

1
2
3
_.now = Date.now || function () {
return new Date().getTime();
}

如果当前的浏览器提供的Date对象中含有now函数就用直接提供的,否则就用自己实现的。平常如果需要生成唯一的id,可以用到这个函数。

_.identity

返回与传入参数相等的值,这个函数看似无用, 但是在Underscore里被用作默认的迭代器iterator.

1
2
3
_.identity = function (value) {
return value;
}

函数非常简单就是你传进来什么东西就返还给你什么东西。

_.constant

创建一个函数,这个函数返回传入的值 。

1
2
3
4
5
_.constant = function (value) {
return function () {
return value;
}
}

_.uniqueId

为需要的客户端模型或DOM元素生成一个全局唯一的id。如果prefix参数存在, id 将附加在其后面。

1
2
3
4
5
var idCounter = 0;
_.uniqueId = function (prefix) {
var id = ++idCounter + ''; // 将数字转化为字符串
return prefix ? prefix + id : id;
}

结语

万事开头难,啥复杂难的事都是从简单容易的事情开始做的,这篇博文主要讲了几个underscore中非常简单的api。接下来会慢慢接触一些比较难的,又非常重要的api。