jquery源码解析:each,makeArray,merge,grep,map详解
jQuery的工具方法,其实就是静态方法,源码里面就是通过extend方法,把这些工具方法添加给jQuery构造函数的。
jQuery.extend({
......
each: function( obj, callback, args ) { //$.each(arr , function(i,value){}),第三个参数用于内部调用。此方法就是来遍历数组的,然后取数组中的值进行显示。不能改变原数组arr,跟map一样,但是map返回新数组,而each返回原数组。这里跟原生的forEach和map的回调方法参数不一样,原生的回调方法中,第三个参数是原数组,可以在回调方法中改变原数组的值。但jQuery的回调方法,不会传第三个参数。
var value,
i = 0,
length = obj.length,
isArray = isArraylike( obj ); //是否是类数组或数组,json(不包括jQuery这种对象形式)返回false
if ( args ) { //jQuery内部使用
if ( isArray ) {
for ( ; i < length; i++ ) {
value = callback.apply( obj[ i ], args );
if ( value === false ) {
break;
}
}
}
else {
for ( i in obj ) {
value = callback.apply( obj[ i ], args );
if ( value === false ) {
break;
}
}
}
}
else { //我们在外面调用时,执行的代码
if ( isArray ) { //如果是类数组
for ( ; i < length; i++ ) {
value = callback.call( obj[ i ], i, obj[ i ] ); //回调方法返回false就停止循环
if ( value === false ) {
break;
}
}
}
else {
for ( i in obj ) { //如果是json对象
value = callback.call( obj[ i ], i, obj[ i ] );
if ( value === false ) {
break;
}
}
}
}
return obj;
},
trim: function( text ) { //core_trim是字符串的trim方法
return text == null ? "" : core_trim.call( text );
},
makeArray: function( arr, results ) { //把所有东西转换成数组,$.makeArray(json) -> [],第二个参数是给内部用的
var ret = results || [];
if ( arr != null ) {
if ( isArraylike( Object(arr) ) ) {
//如果arr为数字123,这里会返回false,因为number不是类数组。但是如果是字符串"hello",Object会把它转成具有length的json对象,所以就返回true。字符串是有length属性的。
jQuery.merge( ret,
typeof arr === "string" ?
[ arr ] : arr
);
}
else { //如果传入123,就执行这里,把123push到数组中。假设有第二个参数,$.makeArray(123,{length:0}) ,那么就会出现[].push.call({length:0},123),这里我做了测试,是没有任何问题的,会变成{length:1,0:123}
core_push.call( ret, arr );
}
}
return ret;
},
inArray: function( elem, arr, i ) { //元素是否在arr数组中,从i位置开始找。core_indexOf=[].indexOf
return arr == null ? -1 : core_indexOf.call( arr, elem, i );
},
merge: function( first, second ) { //合并数组
var l = second.length,
i = first.length,
j = 0;
if ( typeof l === "number" ) { //第二个参数,可能不是数组或类数组,特殊json。第一个参数必须是。
for ( ; j < l; j++ ) {
first[ i++ ] = second[ j ];
}
}
else {
while ( second[j] !== undefined ) { //普通json的情况,{0:"0",1:"1"},但必须是0,1,2...这种
first[ i++ ] = second[ j++ ];
}
}
first.length = i; //当第一个参数,不是数组时,比如是{0:"0",1:"1",length:2},length就需要手动改变
return first;
},
grep: function( elems, callback, inv ) {
//过滤得到一个新数组,$.grep(arr,function(value,index){ return value>2}),arr数组中大于2的,才会返回生成数组。也就是返回true时,才会返回此值生成数组,第三个参数,true,就代表相反的(小于等于2)返回生成数组
var retVal,
ret = [],
i = 0,
length = elems.length;
inv = !!inv; //转换成true or false,不传的时候是undefined,就会变成fase.
for ( ; i < length; i++ ) {
retVal = !!callback( elems[ i ], i ); //转换成true or false
if ( inv !== retVal ) {
ret.push( elems[ i ] );
}
}
return ret;
},
map: function( elems, callback, arg ) { //支持普通json,数组,类数组,特殊json(jQuery对象形式)
//$.map(arr,function(value,index){ return }),通过回调,把返回的值组成一个全新的数组,返回全新的数组。第三个参数内部调用
var value,
i = 0,
length = elems.length,
isArray = isArraylike( elems ), //数组和类数组都可以,jQuery对象形式也可以
ret = [];
if ( isArray ) {
for ( ; i < length; i++ ) {
value = callback( elems[ i ], i, arg );
if ( value != null ) { //回调返回的值不是null或者undefined,就存入新数组中
ret[ ret.length ] = value;
}
}
}
else { //普通json就执行这里,比如:{name:"chaojidan",age:25}
for ( i in elems ) {
value = callback( elems[ i ], i, arg );//callback("chaojidan",name)
if ( value != null ) {
ret[ ret.length ] = value;
}
}
}
return core_concat.apply( [], ret );
//core_concat=[].concat,以防回调方法返回的是数组形式,那么就会出现复合数组,比如:ret = [[1],[2],[3]],通过concat([1],[2],[3]),合并,返回[1,2,3]
},
......
})
加油!
jquery源码解析:each,makeArray,merge,grep,map详解的更多相关文章
- jQuery 源码解析(三十) 动画模块 $.animate()详解
jQuery的动画模块提供了包括隐藏显示动画.渐显渐隐动画.滑入划出动画,同时还支持构造复杂自定义动画,动画模块用到了之前讲解过的很多其它很多模块,例如队列.事件等等, $.animate()的用法如 ...
- jQuery 源码分析(十九) DOM遍历模块详解
jQuery的DOM遍历模块对DOM模型的原生属性parentNode.childNodes.firstChild.lastChild.previousSibling.nextSibling进行了封装 ...
- jQuery 源码分析(十) 数据缓存模块 data详解
jQuery的数据缓存模块以一种安全的方式为DOM元素附加任意类型的数据,避免了在JavaScript对象和DOM元素之间出现循环引用,以及由此而导致的内存泄漏. 数据缓存模块为DOM元素和JavaS ...
- jQuery源码分析(九) 异步队列模块 Deferred 详解
deferred对象就是jQuery的回调函数解决方案,它解决了如何处理耗时操作的问题,比如一些Ajax操作,动画操作等.(P.s:紧跟上一节:https://www.cnblogs.com/grea ...
- JQuery源码解析(一)
写在前面:本<JQuery源码解析>系列是基于一些前辈们的文章进行进一步的分析.细化.修改而写出来的,在这边感谢那些慷慨提供科普文档的技术大拿们. 要查阅JQ的源文件请下载开发版的JQ.j ...
- jQuery 源码解析二:jQuery.fn.extend=jQuery.extend 方法探究
终于动笔开始 jQuery 源码解析第二篇,写文章还真是有难度,要把自已懂的表述清楚,要让别人听懂真的不是一见易事. 在 jQuery 源码解析一:jQuery 类库整体架构设计解析 一文,大致描述了 ...
- jquery源码解析:代码结构分析
本系列是针对jquery2.0.3版本进行的讲解.此版本不支持IE8及以下版本. (function(){ (21, 94) 定义了一些变量和函数, jQuery = function() ...
- jquery 源码解析
静态与实力方法共享设计 遍历方法 $(".a").each() //作为实例方法存在 $.each() //作为静态方法存在 Jquery源码 jQuery.prototype = ...
- jQuery源码解析资源便签
最近开始解读jQuery源码,下面的链接都是搜过来的,当然妙味课堂 有相关的一系列视频,长达100多期,就像一只蜗牛慢慢爬, 至少品读三个框架,以后可以打打怪,自己造造轮子. 完全理解jQuery源代 ...
- 三.jQuery源码解析之jQuery的框架图
这张图片是对jQuery源码截图,一点一点拼出来的. 现在根据这张图片来对jQuery框架做一些说明. 一.16~9404行可以发现,最外层是一个自调用函数.当jQuery初始化时,这个自调用函数包含 ...
随机推荐
- solr的简单部署:在tomcat中启动slor
1,首先要下载solr 途径1: 官网网址: http://lucene.apache.org/ 与Lucene的官网是一个 途径2: 下载历史版本的网址: http://archive.apache ...
- Android中的网络编程
谷歌在Android6.0之后就废弃了使用HttpClinet进行网络连接.所以,这里需要重点学习的是通过HttpUrlConnect进行网络连接. String path="这里是你想要的 ...
- c# winform 解决PictureBox 无法打印全部图片的问题
一. 问题描述 在页面使用PictureBox 加载资料图片后,点击“打印”,只能打印图片首页,较大图片则无法全部打印. 二. 原因分析 PictureBox中打印图片时没有设置继续打印相关属 ...
- 【BZOJ1013】球形空间产生器sphere
高斯消元模板题 #include <cstdio> #include <cstring> #include <algorithm> #include <ios ...
- Runnable和Thread实现多线程的区别(含代码)
转载请注明出处:http://blog.csdn.net/ns_code/article/details/17161237 Java中实现多线程有两种方法:继承Thread类.实现Runnable接口 ...
- Cisco VPP启动流程
Cisco VPP启动流程,有需要的朋友可以参考一下. VPP初始化 VLIB_INIT_FUNCTION用来定义构造函数,注册函数到vlib_main_t->init_function_reg ...
- 服务器监控方案CactiEZ V10.1
CactiEZ中文版是最简单有效的Cacti中文解决方案,整合Spine,RRDTool和美化字体.集成Thold,Monitor,Syslog,Weathermap,Realtime,Errorim ...
- 访问tomcat出现java.lang.IllegalStateException No output folder错误解决方法
访问tomcat出现java.lang.IllegalStateException: No output folder错误解决方法 问题:tomcat分为安装版和解压缩版,解压缩版如果解压到安装盘,在 ...
- 项目中遇到的死锁问题: Lock wait timeout exceeded; try restarting transaction
最近项目中频繁出现 Lock wait timeout exceeded; try restarting transaction这个错误,把我们弄得痛苦不堪啊,为了解决问题,上网上找好多资料,终于把 ...
- sublime 3插件安装记录
安装sublime 3的package control管理器: 从菜单 View - Show Console 或者 ctrl + ~ 快捷键,调出 console.将以下 Python 代码粘贴进去 ...