jQuery 源码分析笔记(2) 变量列表


Posted in Javascript onMay 28, 2011

_jQuery = window.jQuery;
_$ = window.$;
这两个变量是jQuery唯一使用的两个全局变量。在jQuery.noConflict()函数中,会把这两个变量恢复回去。
对于浏览器检测,jQuery使用的是检查UserAgent,而没有使用特性检测。
rwebkit = /(webkit)[ \/]([\w.]+)/,
ropera = /(opear)(?:.*version)?[ \/](\w+)/,
rmsie = /(msie) ([\w.]+)/,
rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/,
初始化函数init
jQuery对JS对象的处理比较绕,而最终目的就是把jQuery选择器得到的结果变成和数组差不多的一个对象。有length,first,last等。因为$("...")就是从DOM树从选择一些节点出来。但是,$还有很多其他功能,比如常用的$(function() { ... })用来页面加载后初始化执行,$("<..>...</...>")来直接得到一个节点,用来append到DOM树中。
接下来从93行开始就是很长的一段init函数。Init: function(selector, context, rootjQuery)
步骤:
1、Selector是非法参数:空字符,null和undefined则直接返回this。即有默认属性的jQuery对象。
2、Selector是DOMElement。即用原生的JS,比如getElementById等得到的元素。那么,相当于把原生的DOM对象用$包装一次。把这个元素放到内部数组的第一个位置,并把length设置为1。然后返回。
3、特殊优化处理$("body")。即document.body元素。
4、Selector是以<开头,以>结尾的字符串。那么假定是想用字符串新建一个DOM元素。比如$("<a href='http://www.cnblogs.com">博客园</a>")。为了安全起见,这里使用了一个正则表达式来检查,到底是<...>...</...>形式还是#id的形式。
quickExpr = /^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/。在quickExpr.exec(selector)后,如果是HTML字符串,那么会得到[match, match, undefined],而#id形式会得到[#id, undefined, id]的结果。这样就把字符串区别开了。
对于HTML字符串,如果只有一个tag,那么直接调用createElement。否则调用一个createFragment辅助函数,这个函数使用createDocumentFragment,然后把所有tag都插进去。
createFragment实现在5892行,这里有一个值得注意的地方就是jQuery对于HTML片段做了缓存处理。而且对于不同的浏览器和元素有不同的处理,作者写了大段的注释说明。归纳起来就是(1)只缓存小于0.5KB的小片段。(2)selected状态不缓存。(3)IE6的<object>和<embed>元素不缓存。(4)WebKit不缓存元素的checked属性。以上这些不缓存的原因是jQuery使用克隆(Clone)节点的方式进行缓存,而2-4提到的情况在Clone时会丢失。jQuery使用了正则,或者jQuery.support辅助函数来进行是否缓存的策略判断。这里先略过。jQuery.support牵扯很多浏览器相关问题。
5、如果在4中检查到是#id,则直接调用document.getElementById
6、如果selector是function,则把这个函数当作是document.ready的事件处理函数
7、剩余的各种情况,比如传入了context等。统一调用一个find(selector)来处理。这个函数以后再议。(5109行,jQuery.find = Sizzle; jQuery.expr = Sizzle.selectors; 表明,其他复杂的selector表达式都扔给Sizzle项目了)
jQuery基本成员
jQuery被设计成一个行为和数组很像的对象。所以需要一些转换方法和基本属性。
1、jquery:版本号。最简单的得到版本号的方式:$().jquery
2、length和size():长度。
3、toArray():转换成JS数组
4、get(num):返回第N个元素。如果传入null,则直接返回toArray()的结果。这里返回的就是DOMElement了。
5、pushStack():参见http://api.jquery.com/pushStack/ 。内部new了一个新的jQuery对象,然后把elems和selector得到的结果合并进去,然后返回这个新的jQuery对象。这里有个prevObject属性的设置,往下看end()函数。
6、each(callback, args):遍历数组内的元素。内部调用了$.each Utiltiy。
7、ready(fn):其实和$(function() { })是等价的。
8、eq(i):i允许正负数字,而且返回的仍然是jQuery对象,只不过只有一个元素了。其实只是slice的包装。
9、first()和last():其实就是eq(0)和eq(-1),很简单的一个包装。
10、slice():根据参数获得数组一部分的引用。内部使用pushStack实现的。所以返回的也是一个新的jQuery对象。
11、map(callback):对每个元素依次调用callback。把原来的元素A的数组映射为元素B的数组。callback就是元素A->元素B的映射函数。函数式编程(FP)里很基础的一个概念。
12、end(): 参见http://api.jquery.com/end 。这个是返回选择器的上一个状态。返回的是jQuery.prevObject属性。这个属性是在pushStack函数里面设置的,它在返回新的jQuery对象之前,把这个新对象的prevObject设置为this。这样多次pushStack之后就变成了一个链表(chain)。而end()就是沿着链表往前走一个节点。经过了selector之后,根的prevObject是document。比如$("body div").prevObject就是Document。
extend函数
在jQuery基本成员之后,所有其他成员都是用extend加上去的。声明:
jQuery.extend = jQuery.fn.extend = function() { }
把target后面的所有object参数的属性全部赋值到target上,如果第一个参数是boolean值,则用来指定是否深拷贝。然后返回修改过的target(不是新对象,extend函数直接修改原对象)。

Javascript 相关文章推荐
页面版文本框智能提示JS代码
Nov 20 Javascript
jQuery关于导航条背景切换效果实现示例
Sep 04 Javascript
深入理解$.each和$(selector).each
May 15 Javascript
Javascript中indexOf()和lastIndexOf应用方法实例
Aug 24 Javascript
Bootstrap select下拉联动(jQuery cxselect)
Jan 04 Javascript
JavaScript队列的应用实例详解【经典数据结构】
Apr 12 Javascript
详解JS中的柯里化(currying)
Aug 17 Javascript
js中的 || 与 &amp;&amp; 运算符详解
May 24 Javascript
详解vue 项目白屏解决方案
Oct 31 Javascript
PHP实现基于Redis的MessageQueue队列封装操作示例
Feb 02 Javascript
vue实现标签云效果的方法详解
Aug 28 Javascript
详解vue-template-admin三级路由无法缓存的解决方案
Mar 10 Javascript
Jquery下:nth-child(an+b)的使用注意
May 28 #Javascript
鼠标滑上去后图片放大浮出效果的js代码
May 28 #Javascript
js原生态函数中使用jQuery中的 $(this)无效的解决方法
May 25 #Javascript
actionscript与javascript的区别
May 25 #Javascript
使用javascript获取flash加载的百分比的实现代码
May 25 #Javascript
JavaScript EasyPager 分页函数
May 25 #Javascript
浅说js变量
May 25 #Javascript
You might like
PHP中file_get_contents高?用法实例
2014/09/24 PHP
ThinkPHP提交表单时默认自动转义的解决方法
2014/11/25 PHP
PHP代码优化技巧小结
2015/09/29 PHP
Zend Framework实现将session存储在memcache中的方法
2016/03/22 PHP
php中的依赖注入实例详解
2019/08/14 PHP
浅析PHP echo 和 print 语句
2020/06/30 PHP
JavaScript类属性的访问方式详解
2014/02/11 Javascript
window.location.href的用法(动态输出跳转)
2014/08/09 Javascript
javascript根据时间生成m位随机数最大13位
2014/10/30 Javascript
5个书写JavaScript代码的坏习惯,看看你中枪了没?
2014/11/06 Javascript
Jquery幻灯片特效代码分享--鼠标点击按钮时切换(1)
2015/08/15 Javascript
AngularJS中监视Scope变量以及外部调用Scope方法
2016/01/23 Javascript
KnockoutJS 3.X API 第四章之数据控制流with绑定
2016/10/10 Javascript
BootStrap中Table隐藏后显示问题的实现代码
2017/08/31 Javascript
Vue组件教程之Toast(Vue.extend 方式)详解
2019/01/27 Javascript
js实现通过开始结束控制的计时器
2019/02/25 Javascript
vue2.0结合Element-ui实战案例
2019/03/06 Javascript
如何修改Vue打包后文件的接口地址配置的方法
2020/04/22 Javascript
[01:46]辉夜杯—打造中国DOTA新格局
2015/12/25 DOTA
python正则表达式re模块详细介绍
2014/05/29 Python
Python中比较特别的除法运算和幂运算介绍
2015/04/05 Python
Python返回真假值(True or False)小技巧
2015/04/10 Python
python交互模式下输入换行/输入多行命令的方法
2019/07/02 Python
Python 如何批量更新已安装的库
2020/05/26 Python
解决TensorFlow程序无限制占用GPU的方法
2020/06/30 Python
基于logstash实现日志文件同步elasticsearch
2020/08/06 Python
python抢购软件/插件/脚本附完整源码
2021/03/04 Python
HTML5 canvas基本绘图之绘制线段
2016/06/27 HTML / CSS
Lookfantastic意大利官网:英国知名美妆购物网站
2019/05/31 全球购物
Watchshop德国:欧洲在线手表No.1
2019/06/20 全球购物
党员查摆问题及整改措施
2014/10/10 职场文书
公司承诺书格式范文
2015/04/28 职场文书
幼儿园迎新生欢迎词
2015/09/30 职场文书
竞聘开场白方式有哪些?
2019/08/28 职场文书
Python机器学习三大件之一numpy
2021/05/10 Python
mysql拆分字符串作为查询条件的示例代码
2022/07/07 MySQL