Underscore并无在原生的JavaScript对象原型中进行扩展,而是像jQuery同样,将数据封装在一个自定义对象中(下文称“Underscore对象”)。生成一个Underscore对象:javascript
<script>html
var jsData = {
name : 'data'
}
// 经过_()方法将对象建立为一个Underscore对象
var underscoreData = _(jsData); //_就是Underscore构造函数的标识java
// underscoreData对象的原型中包含了Underscore中定义的全部方法,你能够任意使用
underscoreData.value();ajax
// 经过value方法获取原生数据, 即jsDatajson
</script>数组
Underscore默认使用_(下划线)来访问和建立对象,但这个名字可能不符合咱们的命名规范,或容易引发命名冲突。咱们能够经过noConflict()方法来改变Underscore的命名,并恢复_(下划线)变量以前的值,例如:服务器
<script type="text/javascript">
var _ = '自定义变量';
</script>
<script type="text/javascript" src="http://handyxuefeng.blog.163.com/blog/underscore/underscore-min.js"></script>
<script type="text/javascript">
console.log(_); // Underscore对象
var us = _.noConflict(); // 将Underscore对象重命名为us, 后面都经过us来访问和建立Underscore对象
console.log(_); // 输出"自定义变量"
</script>函数
Underscore一样支持链式操做,但你须要先调用chain()方法进行声明。this
var arr = [10, 20, 30];
_(arr) //新建一个Underscore对象
.chain() //声明我要链式操做了
.map(function(item){ return item++; })
.first()
.value();spa
咱们能够经过mixin()方法轻松地向Underscore中扩展自定义方法,例如:
_.mixin({
method1: function(object) {
// to do
},
method2: function(arr) {
// to do
},
method3: function(fn) {
// to do
}
});
这些方法被追加到Underscore的原型对象中,全部建立的Underscore对象均可以使用这些方法,它们享有和其它方法一样的环境。
Underscore提供了一个轻量级的模板解析函数,它能够帮助咱们有效地组织页面结构和逻辑。handlebars也是作这个处理的。若是是简单的模板解析,Backbone里面有自带的方法,它使用的就是Underscore中的方法。handlebars处理更复杂的模板解析。举例:
<ul id="element"></ul> //用于显示渲染后的标签
<script type="text/template" id="tpl"> //定义模板,将模板内容放到一个script标签中
<% for(var i = 0; i < list.length; i++) { %>
<% var item = list[i] %>
<li>
<span><%=item.firstName%> <%=item.lastName%></span>
<span><%-item.city%></span>
</li>
<% } %>
</script>
<script type="text/javascript" src="http://handyxuefeng.blog.163.com/blog/underscore/underscore-min.js"></script>
<script type="text/javascript">
var element = $('#element'),// 获取渲染元素和模板内容
tpl = $('#tpl').html();
// 建立数据, 这些数据多是你从服务器获取的
var data = {
list: [
{firstName: '<a href="http://handyxuefeng.blog.163.com/blog/#">Zhang</a>', lastName: 'San', city: 'Shanghai'},
{firstName: 'Li', lastName: 'Si', city: '<a href="http://handyxuefeng.blog.163.com/blog/#">Beijing</a>'},
{firstName: 'Wang', lastName: 'Wu', city: 'Guangzhou'},
{firstName: 'Zhao', lastName: 'Liu', city: 'Shenzhen'}
]
}
// 解析模板, 返回解析后的内容
var html = _.template(tpl, data); //把json数据解析到模板中去,并生成html字符串。
element.html(html); // 将解析后的内容填充到渲染元素
</script>
最后,讲几个underscore中的方法:
map()方法与each()方法的做用、参数相同,但它会将每次迭代函数返回的结果记录到一个新的数组并返回。
map方法在原生的js中是存在的,each方法是重写了原生js的forEach方法,请看博客:http://www.cnblogs.com/chaojidan/p/4142338.html
debounce()方法关注函数执行的间隔,即函数两次的调用时间不能小于指定时间。
throttle()方法更关注函数的执行频率,即在指定频率内函数只会被调用一次。
形像的比喻是橡皮球。若是手指按住橡皮球不放,它就一直受力,不能反弹起来,直到松手。
debounce 的关注点是空闲的间隔时间。
// ajaxQuery 将在中止输入 250 毫秒后执行,若是用户一直输入(空闲的间隔时间小于250ms),那么将不会执行ajaxQuery 。
$('#autocomplete').addEventListener('keyup',debounce(250,function() { ajaxQuery(this.value,renderUI); },true))
主要的应用场景:文本输入keydown 事件,keyup 事件,例如作autocomplete。
形像的比喻是水龙头或机枪,你能够控制它的流量或频率。
throttle 的关注点是连续的执行间隔时间。
// 当窗口大小改变时,以 50 毫秒一次的频率为单位执行定位函数 position。由于用户在拖动窗口时,会触发无数个resize事件,若是不作节流,它会执行无数次回调方法。所以使用节流方法,使每隔50毫秒(间隔时间),才执行回调方法。
window.addEventListener('resize',throttle(50,position,true) );
主要应用场景:window对象的resize和scroll 事件,mousemove鼠标移动事件
加油!