这里整理的是jQuery源码中一些比较晦涩难懂的、内部的、最底层的工具方法,它们多为jQuery的上层api方法服务,目前包括:

  • jQuery.access

jQuery.access: function( elems, fn, key, value, chainable, emptyGet, pass )

在jQuery的众多api方法中,许多方法都有一个非常重要和常见的特征:重载,简单来讲即参数的不同决定了方法的功能不同

例如我们最常使用的几个:jQuery.fn.html()、jQuery.fn.attr()、jQuery.fn.text()、jQuery.fn.css()等等

从这些方法的身上,我们其实可以总结出它们之间一些共同具有的特征:

  • 所有的操作都是在元素节点上
  • 进行的操作都是get或set
  • 都有自己的处理函数
  • 都可以接受函数作为参数干预最终的结果
  • 具备链式调用的能力

源码解析:

  1. // Multifunctional method to get and set values of a collection
  2. // The value/s can optionally be executed if it's a function
  3. /** 参数说明
  4. * elems [object] 元素
  5. * fn [function] 原始处理函数
  6. * key [string|object] 属性名称/键值对列表
  7. * value [type|function] 进行赋值的值/干预函数
  8. * chainable [boolean] 是否可以链式调用
  9. * emptyGet [type] 指定的空值,类型不定
  10. * pass [boolean] 属性与jQuery方法同名时,是否调用jQuery的方法,在attr方法那里会用到
  11. */
  12. access: function( elems, fn, key, value, chainable, emptyGet, pass ) {
  13. var exec,
  14. bulk = key == null,
  15. i = 0,
  16. length = elems.length;
  17.  
  18. // Sets many values
  19. // 如果key是一个键值对对象,那么一定是在赋值,分解key然后递归调用
  20. if ( key && typeof key === "object" ) {
  21. for ( i in key ) {
  22. // 可以看出,赋值操作都是可以继续链式调用,因为chainable直接被赋值为了1
  23. jQuery.access( elems, fn, i, key[i], 1, emptyGet, value );
  24. }
  25.  
  26. // 这里仍然需要手动设置chainable的值为1
  27. // 因为这里并没有return
  28. chainable = 1;
  29.  
  30. // Sets one value
  31. } else if ( value !== undefined ) {
  32. // Optionally, function values get executed if exec is true
  33. // 如果没传pass并且传入了干预函数
  34. exec = pass === undefined && jQuery.isFunction( value );
  35.  
  36. // bulk = key == null
  37. // 即没有传入key,但传了value进来
  38. if ( bulk ) {
  39. // Bulk operations only iterate when executing function values
  40. // value是个函数的情况
  41. if ( exec ) {
  42. // 原始处理函数用exec保存起来
  43. exec = fn;
  44. // 把原本保存原始处理函数的变量fn重新用约定好的结构进行封装,以便后面统一进行调用
  45. // 这里的key参数纯粹是为了在后面的调用处统一参数
  46. // 注意这里的fn函数最后返回了原始处理函数的处理结果,为什么这样做呢?后面解释
  47. fn = function( elem, key, value ) {
  48. return exec.call( jQuery( elem ), value );
  49. };
  50.  
  51. // Otherwise they run against the entire set
  52. } else {
  53. // 这是最简单的情况,直接调用原始处理函数进行赋值
  54. // 这种情况下的赋值操作到这里就已经完成了
  55. // 所以在这里把fn置为了null,因为后面的if已经没有必要执行了
  56. fn.call( elems, value );
  57. fn = null;
  58. }
  59. }
  60.  
  61. // 剔除上面最简单那种情况,无论传不传key的值,这里的if都会执行
  62. if ( fn ) {
  63. for (; i < length; i++ ) {
  64. // 这里的fn的值包含两种情况,一个是原始处理函数,一个是上面已经封装过的fn
  65. // 这里最难理解的应该就是fn( elems[i], key )这句话了
  66. // 首先无论是哪种情况,fn( elems[i], key )这句话一定是一个取值的操作
  67. // 那么如果fn是原始处理函数,并且传入了key的值,取到的其实就是这个元素的原始属性值,把它作为第二个参数传入了干预函数
              // 如$("div").attr( "id", function( index, attr ){} )
  68. // 如果fn是上面封装的函数,表示没有传入key值,则fn中的key和value都是undefined,但仍然仅凭元素就可以取得这个元素的原始属性值,哪种情况呢?
    // 如$("div").text("something")
  69. // 所以,fn( elems[i], key )这句话的作用也就清晰了,就是取得元素的原始属性值
  70. // 搞懂了上面,这行代码也就不难理解了,这里设计的确实是巧啊
  71. fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
  72. }
  73. }
  74.  
  75. // 同样,仍然是可以链式调用
  76. chainable = 1;
  77. }
  78.  
  79. // 如果可以链式调用,返回元素集即可,函数到此结束
  80. // 如果不是,则证明是在取值
  81. // 如果没传key,直接返回fn.call( elems ),如$("div").html()
  82. // 如果传了key,则返回第一个元素的key对应的属性值或返回指定的空值emptyGet
  83. return chainable ?
  84. elems :
  85.  
  86. // Gets
  87. bulk ?
  88. fn.call( elems ) :
  89. length ? fn( elems[0], key ) : emptyGet;
  90. }

  

jQuery晦涩的底层工具方法们的更多相关文章

  1. JQuery --- 第一期 (初识jQuery, JQuery核心函数和工具方法)

    个人学习笔记  初识jQuery 1.我的第一个JQuery <!DOCTYPE html> <html lang="en"> <head> & ...

  2. jQuery源代码 解析一 工具方法

    1. 外层沙箱以及命名空间$ 几乎稍微有点经验前端人员都这么做,为了避免声明了一些全局变量而污染,把代码放在一个"沙箱执行",然后在暴露出命名空间(可以为API,函数,对象): 2 ...

  3. JQuery $ $.extend(),$.fn和$.fn.extend javaScript对象、DOM对象和jQuery对象及转换 工具方法(utility)

    一.为什么jquery前面要写$ Javascript没有package的概念,而作者又希望所有jQuery相关的API都能通过一个全局性的对象来容纳. 名为jQuery的全局变量就是这样一个对象,不 ...

  4. JavaScript1.6数组新特性和JQuery的几个工具方法

    JavaScript 1.6 引入了几个新的Array 方法,具体的介绍见:New in JavaScript 1.6 .这些方法已经被写进了ECMA262 V5.现代浏览器(IE9/Firefox/ ...

  5. JQuery extend()与工具方法、实例方法

    使用jQuery的时候会发现,jQuery中有的函数是这样使用的: $.get(); $.post(); $.getJSON(); 有些函数是这样使用的: $('div').css(); $('ul' ...

  6. JQuery操作类数组的工具方法

    JQuery学习之操作类数组的工具方法 在很多时候,JQuery的$()函数都返回一个类似数据的JQuery对象,例如$('div')将返回div里面的所有div元素包装的JQuery对象.在这中情况 ...

  7. jQuery工具方法

    目录 常用工具方法 判断数据类型的方法 Ajax操作 $.ajax 简便写法 Ajax事件 返回值 JSONP 文件上传 参考链接 jQuery函数库提供了一个jQuery对象(简写为$),这个对象本 ...

  8. jQuery常用工具方法

    前面的话 jQuery提供一些与元素无关的工具方法,不必选中元素,就可以直接使用这些方法.如果理解原生javascript的继承原理,那么就能理解工具方法的实质.它是定义在jQuery构造函数上的方法 ...

  9. jquery中的工具方法$.isFunction, $.isArray(), $.isWindow()

    本文正式地址:http://www.xiabingbao.com/jquery/2015/07/25/jquery-judge-type 在javascript中对变量类型的判断中,我们讲解了了jqu ...

随机推荐

  1. PNG和Gif及JPEG图片格式比较

    Gif格式特点 透明性Gif是一种布尔透明类型,既它可以是全透明,也可以是全不透明,但是它并没有半透明(alpha 透明). 动画Gif这种格式支持动画. 无损耗性Gif是一种无损耗的图像格式,这也意 ...

  2. 20145205 《Java程序设计》第6周学习总结

    教材学习内容总结 -若要将数据从来源中取出,可以使用输入串流:若要将数据写入目的地,可以使用输出串流.在java中,输入串流代表对象为java.in.InputStream的实例:输出串流代表对象为j ...

  3. ccf模板生成

    问题描述 成成最近在搭建一个网站,其中一些页面的部分内容来自数据库中不同的数据记录,但是页面的基本结构是相同的.例如,对于展示用户信息的页面,当用户为 Tom 时,网页的源代码是 而当用户为 Jerr ...

  4. SqlServer 笔记一 某表中每个月的产品数量(DATENAME() 与 DATEPART()、YEAR())

    1.使用 DATENAME() 函数 SELECT DATENAME(yyyy, [columnName]) + '/' + DATENAME(mm, [columnName]) AS monthDa ...

  5. WIN7 如何将BAT文件附加到任务栏

    1.桌面有个 a.bat 文件2.将a.bat 改名为 a.exe3.将 a.exe 拉到任务栏4.修改桌面的 a.exe 回 a.bat5.打开C:\Users\Administrator\AppD ...

  6. Nginx中FastCGI配置优化

    FastCGI: FastCGI是从CGI发展改进而来的.传统CGI接口方式的主要缺点是性能很差,因为每次HTTP服务器遇到动态程序时都需要重新启动脚本解析器来执行解析,然后结果被返回给HTTP服务器 ...

  7. 修改SQL SERVER表,并添加说明

    alter table dbo.user_PersonManagement add F_FGBM nvarchar(500)GO EXEC sys.sp_addextendedproperty @na ...

  8. 获取EMF文件内全部文字, 并按照左上到右下的顺序排序

    因为工作要求, 需要对EMF文件文字内容做分析.....SO, 如下代码出现了 懒得加注释了, 反正对外接口属性就那么几个, 根据英文猜吧, 很容易的 说明一下: 这个东西结果会对所有文字内容按照左上 ...

  9. VS2012完全卸载与VS2013安装

    项目本来使用的是vs2012 Ultimate,也一直跟随ms的节奏安装了从1到4的update,但一些无法忍受的问题却一直没有解决: 1.偶尔出现要等待编辑器响应的情况: 2.偶尔输入了冒号也不会出 ...

  10. Python学习【第九篇】函数

    函数 函数是什么? 函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段. 在学习函数之前,一直遵循:面向过程编程,即:根据业务逻辑从上而下实现功能,其往往用一段代码来实现指定功能,开发过 ...