这里整理的是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
  • 都有自己的处理函数
  • 都可以接受函数作为参数干预最终的结果
  • 具备链式调用的能力

源码解析:

// Multifunctional method to get and set values of a collection
// The value/s can optionally be executed if it's a function
/** 参数说明
* elems [object] 元素
* fn [function] 原始处理函数
* key [string|object] 属性名称/键值对列表
* value [type|function] 进行赋值的值/干预函数
* chainable [boolean] 是否可以链式调用
* emptyGet [type] 指定的空值,类型不定
* pass [boolean] 属性与jQuery方法同名时,是否调用jQuery的方法,在attr方法那里会用到
*/
access: function( elems, fn, key, value, chainable, emptyGet, pass ) {
var exec,
bulk = key == null,
i = 0,
length = elems.length; // Sets many values
// 如果key是一个键值对对象,那么一定是在赋值,分解key然后递归调用
if ( key && typeof key === "object" ) {
for ( i in key ) {
// 可以看出,赋值操作都是可以继续链式调用,因为chainable直接被赋值为了1
jQuery.access( elems, fn, i, key[i], 1, emptyGet, value );
} // 这里仍然需要手动设置chainable的值为1
// 因为这里并没有return
chainable = 1; // Sets one value
} else if ( value !== undefined ) {
// Optionally, function values get executed if exec is true
// 如果没传pass并且传入了干预函数
exec = pass === undefined && jQuery.isFunction( value ); // bulk = key == null
// 即没有传入key,但传了value进来
if ( bulk ) {
// Bulk operations only iterate when executing function values
// value是个函数的情况
if ( exec ) {
// 原始处理函数用exec保存起来
exec = fn;
// 把原本保存原始处理函数的变量fn重新用约定好的结构进行封装,以便后面统一进行调用
// 这里的key参数纯粹是为了在后面的调用处统一参数
// 注意这里的fn函数最后返回了原始处理函数的处理结果,为什么这样做呢?后面解释
fn = function( elem, key, value ) {
return exec.call( jQuery( elem ), value );
}; // Otherwise they run against the entire set
} else {
// 这是最简单的情况,直接调用原始处理函数进行赋值
// 这种情况下的赋值操作到这里就已经完成了
// 所以在这里把fn置为了null,因为后面的if已经没有必要执行了
fn.call( elems, value );
fn = null;
}
} // 剔除上面最简单那种情况,无论传不传key的值,这里的if都会执行
if ( fn ) {
for (; i < length; i++ ) {
// 这里的fn的值包含两种情况,一个是原始处理函数,一个是上面已经封装过的fn
// 这里最难理解的应该就是fn( elems[i], key )这句话了
// 首先无论是哪种情况,fn( elems[i], key )这句话一定是一个取值的操作
// 那么如果fn是原始处理函数,并且传入了key的值,取到的其实就是这个元素的原始属性值,把它作为第二个参数传入了干预函数
          // 如$("div").attr( "id", function( index, attr ){} )
// 如果fn是上面封装的函数,表示没有传入key值,则fn中的key和value都是undefined,但仍然仅凭元素就可以取得这个元素的原始属性值,哪种情况呢?
// 如$("div").text("something")
// 所以,fn( elems[i], key )这句话的作用也就清晰了,就是取得元素的原始属性值
// 搞懂了上面,这行代码也就不难理解了,这里设计的确实是巧啊
fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
}
} // 同样,仍然是可以链式调用
chainable = 1;
} // 如果可以链式调用,返回元素集即可,函数到此结束
// 如果不是,则证明是在取值
// 如果没传key,直接返回fn.call( elems ),如$("div").html()
// 如果传了key,则返回第一个元素的key对应的属性值或返回指定的空值emptyGet
return chainable ?
elems : // Gets
bulk ?
fn.call( elems ) :
length ? fn( elems[0], key ) : emptyGet;
}

  

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. phpcms无刷新分页

    控制器添加一个函数: 添加一个静态页面ajax_message.html,在页面中添加如下代码: 在要分页的页面(我的是"show"页面)中添加如上图代码: phpcms无刷新分页 ...

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

    教材学习内容总结 认识时间与日期 1.格林威治时间(GMT):通过观察太阳而得,因为地球公转轨道为椭圆形且速度不一,本身自传减速而造成误差. 2.世界时(UT):通过观测远方星体跨过子午线而得,受地球 ...

  3. Java备份Oracle数据库

    Java备份Oracle数据库 Java线程.Process.ProcessBuilder 2010 年 6 月 20 日 文章内容描述了使用Java执行外部Oracle导出命令备份数据库功能的示例, ...

  4. c# WinForm中使用DevExpress.XtraSpreadsheet.SpreadsheetControl时,给sheet批量赋值

    即使看了Demo,我也是很久才搞清除的,可能是我太笨了 首先在form上添加一个spreadsheetcontrol控件,添加各种引用: 然后添加引用: using DevExpress.XtraEd ...

  5. win7下利用VM8安装CentOS6.3配置静态IP上网

    1 环境 宿主主机64位win7,利用VM8安装的64位CentOS6.3,64位的.在VM中配置CentOS的IP为静态,可上互联网.具体配置过程如下. 2 步骤 首先将VM的setting选项中, ...

  6. 记一次【求n以内的素数个数】的优化记录

    最近在leetCode上刷提,还是满锻炼人的,为以后面试打基础吧.不多说下面开始. 问题:求[2,n]之间的素数的个数. 来源:leetCode OJ 提示: Let's start with a i ...

  7. iphone状态栏高度?

      设备分辨率         状态栏高度           导航栏高度 标签栏高度 iPhone6 plus       1242×2208 px           60px           ...

  8. C和C++混合编程中的extern "C" {}

    引言 在用C++的项目源码中,经常会不可避免的会看到下面的代码: 1 2 3 4 5 6 7 8 9 #ifdef __cplusplus extern "C" { #endif ...

  9. chrome中hack解决input:-webkit-autofill自定义样式

    在使用chrome浏览器设计网页时,想将input背景改成透明,也就是 background-color:transparent; 可是效果并不如人意 hack方法: input:-webkit-au ...

  10. idea使用心得(2)-安装设置与创建web项目

    idea 是与eclipse齐名的IDE(集成开发工具),以智能闻名,不过对于熟悉eclipse的的用户来说,初次接触idea有些让人搞不清方向,下面介绍一下简单的使用 方式. 1.安装 官网下载ul ...