jQuery晦涩的底层工具方法们
这里整理的是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晦涩的底层工具方法们的更多相关文章
- JQuery --- 第一期 (初识jQuery, JQuery核心函数和工具方法)
个人学习笔记 初识jQuery 1.我的第一个JQuery <!DOCTYPE html> <html lang="en"> <head> & ...
- jQuery源代码 解析一 工具方法
1. 外层沙箱以及命名空间$ 几乎稍微有点经验前端人员都这么做,为了避免声明了一些全局变量而污染,把代码放在一个"沙箱执行",然后在暴露出命名空间(可以为API,函数,对象): 2 ...
- JQuery $ $.extend(),$.fn和$.fn.extend javaScript对象、DOM对象和jQuery对象及转换 工具方法(utility)
一.为什么jquery前面要写$ Javascript没有package的概念,而作者又希望所有jQuery相关的API都能通过一个全局性的对象来容纳. 名为jQuery的全局变量就是这样一个对象,不 ...
- JavaScript1.6数组新特性和JQuery的几个工具方法
JavaScript 1.6 引入了几个新的Array 方法,具体的介绍见:New in JavaScript 1.6 .这些方法已经被写进了ECMA262 V5.现代浏览器(IE9/Firefox/ ...
- JQuery extend()与工具方法、实例方法
使用jQuery的时候会发现,jQuery中有的函数是这样使用的: $.get(); $.post(); $.getJSON(); 有些函数是这样使用的: $('div').css(); $('ul' ...
- JQuery操作类数组的工具方法
JQuery学习之操作类数组的工具方法 在很多时候,JQuery的$()函数都返回一个类似数据的JQuery对象,例如$('div')将返回div里面的所有div元素包装的JQuery对象.在这中情况 ...
- jQuery工具方法
目录 常用工具方法 判断数据类型的方法 Ajax操作 $.ajax 简便写法 Ajax事件 返回值 JSONP 文件上传 参考链接 jQuery函数库提供了一个jQuery对象(简写为$),这个对象本 ...
- jQuery常用工具方法
前面的话 jQuery提供一些与元素无关的工具方法,不必选中元素,就可以直接使用这些方法.如果理解原生javascript的继承原理,那么就能理解工具方法的实质.它是定义在jQuery构造函数上的方法 ...
- jquery中的工具方法$.isFunction, $.isArray(), $.isWindow()
本文正式地址:http://www.xiabingbao.com/jquery/2015/07/25/jquery-judge-type 在javascript中对变量类型的判断中,我们讲解了了jqu ...
随机推荐
- Servlet读取资源文件(文件的下载)
1. 文件名非中文: package ztq.servlet.study; import java.io.FileInputStream; import java.io.IOException; im ...
- 20145205 《Java程序设计》第6周学习总结
教材学习内容总结 -若要将数据从来源中取出,可以使用输入串流:若要将数据写入目的地,可以使用输出串流.在java中,输入串流代表对象为java.in.InputStream的实例:输出串流代表对象为j ...
- 《大道至简》第一章读后感(java语言伪代码)
中秋放假之际读了建民老师介绍的<大道至简>的第一章,其中以愚公移山的故事形象的介绍向介绍编程的精义.愚公的出现要远远早于计算机发展的历史,甚至早于一些西方国家的文明史.但是,这个故事许是我 ...
- WM_COPYDATA进程间通信方案
连续在两个公司使用WM_COPYDATA实现进程间通信了,整理一下 具体步骤: 一. 进程A通过ShellExecute启动进程B, 将用于通信的窗口句柄hWndA(已强转为int值)通过命令行参 ...
- Zxing库
一.介绍 Zxing是一个开放的源码,用java实现的多种样式的1D/2D条码处理库,它包含了联系到其他语言的端口.Zxing可以实现手机的内置摄像头完成条码的扫描及解码.目前支持:UPC-A ,UP ...
- 快速理解几种常用的RAID磁盘阵列级别
我发现周围不少人在学习和理解RAID磁盘阵列的原理时,找了很多专业的资料来看,但是因为动手的机会比较少,因此看完以后还是似懂非懂,真正遇到实际的方案设计的时候,还是拿不定主意. 因此,我结合自己在过去 ...
- WebApp中的页面生命周期及路由管理
最近切换到一个新项目,使用的技术栈是Require+Backbone,鉴于对鞋厂webapp框架的了解,发现这个新项目有些缺陷,主要是单纯依赖Backbone造成的,也就是Backbone的好和坏都在 ...
- C#发送邮件时提示:“不允许使用邮箱名称。服务器响应为:”的错误解决办法
由于项目需要,要为客户提供一个定期发送邮件的程序.本来原来自己还写过,但新写的程序一晚上也没通过测试,总是提示"不允许使用邮箱名称.服务器响应为..." 经过在网上搜索查找解决办法 ...
- POST流方式接受数据方法
/** * 流方式接收数据 * @param $url * @param $jsonFile * @return bool */private static function sendStreamJs ...
- Spark java.lang.outofmemoryerror gc overhead limit exceeded 与 spark OOM:java heap space 解决方法
引用自:http://cache.baiducontent.com/c?m=9f65cb4a8c8507ed4fece7631046893b4c4380146d96864968d4e414c42246 ...