underscore.js依赖库函数分析二(查找)
查找:
在underscore.js封装了对dom查找的操作,find()和filter()函数,find()函数的查找操作是返回首个与条件相符的元素值,filter()函数是找到与条件相符的所有元素,则返回的就是一个数组,如果没有找到符合条件,则返回一个空的数组。接下来一个个分析:
find()函数:
该函数根据iterator迭代器中的自定义函数条件,在集合列表中查找符合条件的第一个元素,如果找到,则返回第一个元素,否则返回“undefined”。
实例:
/**
* Created by 蒯灵敏 on 14-10-5.
*/
$(function(){
var list = [1,2,3,4,5];
var first = _.find(list,function(n){
return (!( n % 2 == 0));
});
console.log(first);
});
运行结果测返回第一个符合条件的元素 1,单纯看例子很简单,如果分析源码就会发现设计者的思路是怎么实现这个的,
源码:
// Return the first value which passes a truth test. Aliased as `detect`.
_.find = _.detect = function(obj, iterator, context) {
// result存放第一个能够通过验证的元素
var result;
// 通过any方法遍历数据, 并记录通过验证的元素
any(obj, function(value, index, list) {
// 如果处理器返回的结果被转换为Boolean类型后值为true, 则记录当前值并返回当前元素
if (iterator.call(context, value, index, list)) {
result = value;
return true;
}
});
return result;
};
在上面的例子中我们给find()函数传入的是一个集合,到源码这里参数为obj,程序拿到这个集合直接递给了一个any的函数进行真正的逻辑处理,看下这个any到底是怎么处理查找操作的:
源码:
// Determine if at least one element in the object matches a truth test.
// Delegates to **ECMAScript 5**'s native `some` if available.
// Aliased as `any`.
var any = _.some = _.any = function(obj, iterator, context) {
// 如果没有指定处理器参数, 则使用默认的处理器函数,该函数会返回参数本身
iterator || (iterator = _.identity);
var result = false;
//如果obj参数为空则返回一个false值参数
if (obj == null) return result;
// 优先调用宿主环境提供的some方法
if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context);
// 迭代集合中的元素
each(obj, function(value, index, list) {
if (result || (result = iterator.call(context, value, index, list))) return breaker;
}); //这里返回一个boolean值参数
return !!result;
};
注:这里返回值得写法是双感叹号“!!”,说明下,javascript是弱类语音,变量没有固定的类型,于是通过这种在表达式或变量前面添加符号的方式来声明类型,这里的双感叹号将后面表达式或变量转换成boolean类型,如同三元表达式,
看下面的代码就能一目了然:
var val = !!document.getElementById
换种思路呈现:
var val = document.getElementById ? true : false;
以上是find()函数的源码分析,下面是filter()函数
filter()函数:
该函数根据iterator迭代器的自定义函数条件,在集合列表中寻找符合条件的元素,返回出来的是一个数组。
实例:
/**
* Created by 蒯灵敏 on 14-10-5.
*/
$(function(){
var list = [1,2,3,4,5];
var first = _.filter(list,function(n){
return (!( n % 2 == 0));
});
console.log(first);
});
这段代码把符合条件的元素返回成一个数组,结果是[1,3,5]
源码:
// Return all the elements that pass a truth test.
// Delegates to **ECMAScript 5**'s native `filter` if available.
// Aliased as `select`.
_.filter = _.select = function(obj, iterator, context) {
//设置返回参数
var results = [];
if (obj == null) return results;
// 优先调用宿主环境提供的filter方法
if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context);
each(obj, function(value, index, list) {
if (iterator.call(context, value, index, list)) results.push(value);
});
return results;
};
注:这里obj.filter的用法纯 js的方式实现,现代浏览器已经支持对each, filter, map, reduce的支持,在underscore.js中有些函数都会有个判断规律,就是先判断当前浏览器是否支持一些js原生态的方法,支持则直接调用,不支持走其他的逻辑程序。
以上是underscore中的查询。还有很多知识点去学,继续激情的前进着。。。
underscore.js依赖库函数分析二(查找)的更多相关文章
- underscore.js依赖库函数分析一(遍历)
Underscore简介: underscore是一个非常简洁,实用的javascript库,和jQuery封装类型差不多,但underscore是backbone的依赖 库,想运行backbone就 ...
- underscore.js 源码分析5 基础函数和each函数的使用
isArrayLike 检测是数组对象还是纯数组 var property = function(key) { return function(obj) { return obj == null ? ...
- Vue.js 源码分析(二十七) 高级应用 异步组件 详解
当我们的项目足够大,使用的组件就会很多,此时如果一次性加载所有的组件是比较花费时间的.一开始就把所有的组件都加载是没必要的一笔开销,此时可以用异步组件来优化一下. 异步组件简单的说就是只有等到在页面里 ...
- Vue.js 源码分析(二十六) 高级应用 作用域插槽 详解
普通的插槽里面的数据是在父组件里定义的,而作用域插槽里的数据是在子组件定义的. 有时候作用域插槽很有用,比如使用Element-ui表格自定义模板时就用到了作用域插槽,Element-ui定义了每个单 ...
- Vue.js 源码分析(二十九) 高级应用 transition-group组件 详解
对于过度动画如果要同时渲染整个列表时,可以使用transition-group组件. transition-group组件的props和transition组件类似,不同点是transition-gr ...
- Vue.js 源码分析(二十八) 高级应用 transition组件 详解
transition组件可以给任何元素和组件添加进入/离开过渡,但只能给单个组件实行过渡效果(多个元素可以用transition-group组件,下一节再讲),调用该内置组件时,可以传入如下特性: n ...
- Vue.js 源码分析(二十五) 高级应用 插槽 详解
我们定义一个组件的时候,可以在组件的某个节点内预留一个位置,当父组件调用该组件的时候可以指定该位置具体的内容,这就是插槽的用法,子组件模板可以通过slot标签(插槽)规定对应的内容放置在哪里,比如: ...
- Vue.js 源码分析(二十四) 高级应用 自定义指令详解
除了核心功能默认内置的指令 (v-model 和 v-show),Vue 也允许注册自定义指令. 官网介绍的比较抽象,显得很高大上,我个人对自定义指令的理解是:当自定义指令作用在一些DOM元素或组件上 ...
- Vue.js 源码分析(二十三) 指令篇 v-show指令详解
v-show的作用是将表达式值转换为布尔值,根据该布尔值的真假来显示/隐藏切换元素,它是通过切换元素的display这个css属性值来实现的,例如: <!DOCTYPE html> < ...
随机推荐
- @RequestMapping详解
简介: @RequestMapping RequestMapping是一个用来处理请求地址映射的注解,可用于类或方法上.用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径. RequestM ...
- Django环境配置
Django安装 #安装最新版本的Django $ pip install django #或者指定安装版本 pip install -v django==1.7.1 项目创建 $ django-ad ...
- 开发一款完备的android应用所必备的知识
原文:http://blog.csdn.net/xyz_lmn/article/details/17575709
- JavaWeb学习之JSP常用标签、EL表达式的运算符、JSTL标签库(6)
1.JSP常用标签 * 只要支持JSP文件,常用标签有可以直接使用 * 格式: jsp:xxxx * jsp:forward ,完成jsp页面的转发 * page属性:转发的地址 <% requ ...
- sql server 用户'sa'登录失败(错误18456)(转载)
转载地址:http://thenear.blog.51cto.com/4686262/865544 用户'sa'登录失败(错误18456)解决方案图解 当我们在使用sql server 的时候可能会遇 ...
- 从 Eclipse 迁移至 Android Studio
从 Eclipse 迁移至 Android Studio 本文内容 Android Studio 基础知识 迁移先决条件 将项目导入 Android Studio 后续步骤 将项目迁移至 Androi ...
- hdu 4049 2011北京赛区网络赛J 状压dp ***
cl少用在for循环里 #include<cstdio> #include<iostream> #include<algorithm> #include<cs ...
- 直传文件到Azure Storage的Blob服务中
(此文章同时发表在本人微信公众号“dotNET每日精华文章”,欢迎右边二维码来关注.) 题记:为了庆祝获得微信公众号赞赏功能,忙里抽闲分享一下最近工作的一点心得:如何直接从浏览器中上传文件到Azure ...
- Ubuntu下配置samba实现文件夹共享
转自:http://www.cnblogs.com/phinecos/archive/2009/06/06/1497717.html 一. samba的安装: sudo apt-get insall ...
- linux SecureCRT ssh key认证登陆
转自:http://blog.chinaunix.net/uid-20639775-id-3207171.html 通过SecureCRT创建key登录认证 一.生成公钥/密钥对 使用SecureCR ...