本文将分析jQuery对象操作相关方法(包括静态和实例方法):

merge方法,代码如下:

 //此方法用于合并两个jQuery对象(因为jQuery对象中有length属性)或者数组,//这个方法非常简单,就是简单的追加第二个对象的属性到第一个对象上去merge: function( first, second ) {var i = first.length,j = 0;if ( typeof second.length === "number" ) {for ( var l = second.length; j < l; j++ ) {first[ i++ ] = second[ j ];}} else {while ( second[j] !== undefined ) {first[ i++ ] = second[ j++ ];}}first.length = i;return first;}, 

可以看到此方法非常简单,但它在jQuery内部应用的地方却是非常多的,包括init方法,pushStack方法,makeArray方法里都用到了此方法。

pushStack方法,代码如下:

     pushStack: function( elems, name, selector ) {//constructor指向jQuery方法本身,那自然ret会被创建为一个空的jQuery对象(可作为一个元素集)//此时等效为 var ret = jQuery();// Build a new jQuery matched element setvar ret = this.constructor();if ( jQuery.isArray( elems ) ) {//push是Array.prototype.push的一个shortcut,此时将elems添加到ret中push.apply( ret, elems );} else {jQuery.merge( ret, elems );}// 保存操作前的对象// Add the old object onto the stack (as a reference)ret.prevObject = this;ret.context = this.context;if ( name === "find" ) {ret.selector = this.selector + (this.selector ? " " : "") + selector;} else if ( name ) {ret.selector = this.selector + "." + name + "(" + selector + ")";}// Return the newly-formed element setreturn ret;},

要注意的是pushStack方法并不对源对象做破坏性更改(所谓破坏性更改,是指对原jQuery对象中选择的元素有变动的更改),而是返回新的 jQuery对象,因此在使用时需要注意。也就是说诸如下面的代码在使用时容易使人迷惑,其实obj并未把DOM元素加入到当前的jQuery栈,而我们 将元素加入当前jQuery栈的一般做法还是用选择器来实现:

   var obj = $("a");ret = obj.pushStack(document.getElementsByTagName("span")).pushStack(document.getElementsByTagName("input"));//obj依然是包含a元素的jQuery对象console.log(obj); //[<a>?</a>?]//ret则仅仅包含inputconsole.log(ret); //[<input type=?"button" id=?"btn" value=?"click!">?] 

之所以把pushStack设置为实例方法而非静态方法,就是为了在jQuery中实现一个undo操作的功能,更多可以参见jQuery文档中关于end方法的使用。

其实pushStack本身在jQuery文档中也未公开,作为Internals方法存在,因此不建议使用此方法,但是在jQuery内部经常看到此方法出现,比如下面即将说到的map方法:

   //该方法将返回经过callback过滤后的jQuery对象,map: function( callback ) {return this.pushStack( jQuery.map(this, function( elem, i ) {return callback.call( elem, i, elem );}));},

由于实例map方法调用了静态map方法,我们接着看看静态map方法:

 // arg is for internal usage onlymap: function( elems, callback, arg ) {var value, key, ret = [],i = 0,length = elems.length,// 传入jQuery对象时,将会把jQuery对象也作为数组来处理// jquery objects are treated as arraysisArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ;// Go through the array, translating each of the items to theirif ( isArray ) {for ( ; i < length; i++ ) {value = callback( elems[ i ], i, arg );//必须有返回值if ( value != null ) {ret[ ret.length ] = value;}}// Go through every key on the object,} else {for ( key in elems ) {value = callback( elems[ key ], key, arg );if ( value != null ) {ret[ ret.length ] = value;}}}// 最后连接数组,这样做是为了防止空项出现// Flatten any nested arraysreturn ret.concat.apply( [], ret );}, 

map方法和each方法非常的相似,其区别在于,map提供了一个数组到另一个数组映射的功能,而each则单纯地队对象或数组是进行迭代访问,这要求我们必须在使用map时,回调函数必须提供返回值,否则将在返回值中删除该项。

另一个容易混淆的数组遍历方法是grep:

  grep: function( elems, callback, inv ) {var ret = [], retVal;inv = !!inv;  //小提示,!!是为了确保inv转换为bool值,当不传递inv时,!!undefined便等于false// Go through the array, only saving the items// that pass the validator functionfor ( var i = 0, length = elems.length; i < length; i++ ) {retVal = !!callback( elems[ i ], i );if ( inv !== retVal ) {//默认回调函数返回false时将不保留此项ret.push( elems[ i ] );}}return ret;}, 

很容易知道我们在迭代数组时,必须要求回调函数中返回一个bool值来确定该项是否保留。

grep和map方法在文档中属于实用工具(Utilities),由于概念相近,因此放在这里讲解。

jQuery 1.6 源码学习(六)——core.js[6]之jQuery对象/数组操作相关方法相关推荐

  1. (转载)jQuery 1.6 源码学习(一)——core.js[1]之基本架构

    在网上下了一个jQuery 1.2.6的源码分析教程,看得似懂非懂,于是还是去github上下载源码,然后慢慢看源代码学习,首先来说说core.js这个核心文件吧. jQuery整体的基本架构说起来也 ...

  2. [spring源码学习]六、IOC源码-BeanFactory和factory-bean

    https://www.cnblogs.com/jyyzzjl/p/5459335.html 一.代码实例 在我们分析spring的IOC源码的时候,发现除了配置标准的bean,并且通过getBean ...

  3. RocketMQ源码学习(六)-Name Server

    问题列表: Name Server 的作用是什么? Name Server 存储了Broker的什么信息? Name Server 为Producer的提供些什么信息? Name Server 为Co ...

  4. ASP.NET Core 源码学习之Logging[1]:Introduction

    在ASP.NET 4.X中,我们通常使用 log4net, NLog 等来记录日志,但是当我们引用的一些第三方类库使用不同的日志框架时,就比较混乱了.而在 ASP.Net Core 中内置了日志系统, ...

  5. mutations vuex 调用_Vuex源码学习(六)action和mutation如何被调用的(前置准备篇)...

    前言 Vuex源码系列不知不觉已经到了第六篇.前置的五篇分别如下: 长篇连载:Vuex源码学习(一)功能梳理 长篇连载:Vuex源码学习(二)脉络梳理 作为一个Web前端,你知道Vuex的instal ...

  6. jQuery源码学习之Callbacks

    jQuery源码学习之Callbacks jQuery的ajax.deferred通过回调实现异步,其实现核心是Callbacks. 使用方法 使用首先要先新建一个实例对象.创建时可以传入参数flag ...

  7. ASP.NET Core 源码学习之 Logging[2]:Configure

    在上一章中,我们对 ASP.NET Logging 系统做了一个整体的介绍,而在本章中则开始从最基本的配置开始,逐步深入到源码当中去. 默认配置 在 ASP.NET Core 2.0 中,对默认配置做 ...

  8. ASP.NET Core 源码学习之 Options[4]:IOptionsMonitor

    前面我们讲到 IOptions 和 IOptionsSnapshot,他们两个最大的区别便是前者注册的是单例模式,后者注册的是 Scope 模式.而 IOptionsMonitor 则要求配置源必须是 ...

  9. ASP.NET Core 源码学习之 Options[3]:IOptionsSnapshot

    2017-06-28 更新: OptionsSnapshot 已改为 OptionsManager 变更详情 IOptionsCache 已改为 IOptionsMonitorCache 变更详情 在 ...

最新文章

  1. 用OpenCV和深度学习进行年龄识别
  2. linux resouce,platform_device和platform_driver驱动的关系
  3. ASP.NET没有魔法——ASP.NET MVC 与数据库之MySQLEF
  4. 剑指Offer - 面试题17. 打印从1到最大的n位数
  5. Spring Boot 面试问题
  6. SDN中还有路由协议嘛?
  7. C# EXCEL 透视表使用 多行多列的导出透视表
  8. chemdraw怎么画拐弯的箭头_教你画系列,像金属一样有复杂反光的漆皮材质
  9. 人工智能课程设计——植物识别专家系统
  10. 中年失业是一种什么体验
  11. 计算机与通信工程学院运动会海报,【图文】运动会宣传海报资料
  12. 合宙Air720UH链接阿里云流程
  13. C/C++整数除法以及保留小数位的问题
  14. 开放式社区?太小儿科了,智慧城市才是重点
  15. 再见2017,你好2018!
  16. 【译文】学习深度学习的四个步骤
  17. Jmeter5.x性能压测工具入门介绍
  18. linux系统线程通信的几种方式,Linux进程间通信-线程间通信
  19. 采用直线逼近方式的圆弧插补
  20. 投资日记 11.2中心从科技板逐渐转换到食品版块

热门文章

  1. ExecutorService框架
  2. Nginx源码分析:核心模块剖析及常见问题
  3. Linux crontab 命令格式与详细例子
  4. luoguP2657 [SCOI2009]windy数
  5. springboot使用hibernate validator校验
  6. 利用yarn capacity scheduler在EMR集群上实现大集群的多租户的集群资源隔离和quota限制...
  7. 记录某段程序的运行时间
  8. VS2015 ionic 开发环境配置纪要
  9. [排序算法] 选择排序(2种)
  10. jquery-validation插件