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 相关文章推荐
JavaScript实现禁止后退的方法
Dec 27 Javascript
?牟┛途W扣了一??效果出?? target=
May 27 Javascript
Extjs Ext.MessageBox.confirm 确认对话框详解
Apr 02 Javascript
在IE 浏览器中使用 jquery的fadeIn() 效果 英文字符字体加粗
Jun 02 Javascript
解决IE6的PNG透明JS插件使用介绍
Apr 17 Javascript
使用javascript实现监控视频播放并打印日志
Jan 05 Javascript
javascript实现按回车键切换焦点
Feb 09 Javascript
JS实现的表格行鼠标点击高亮效果代码
Nov 27 Javascript
详解VueJs中的V-bind指令
May 03 Javascript
详解关于JSON.parse()和JSON.stringify()的性能小测试
Mar 14 Javascript
详解JavaScript作用域、作用域链和闭包的用法
Sep 03 Javascript
JavaScript 对象创建的3种方法
Nov 17 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提示Deprecated: mysql_connect(): The mysql extension is deprecated的解决方法
2014/08/28 PHP
php中spl_autoload详解
2014/10/17 PHP
Joomla调用系统自带编辑器的实现方法
2016/05/05 PHP
Yii2.0使用阿里云OSS的SDK上传图片、下载、删除图片示例
2017/09/20 PHP
thinkphp框架使用JWTtoken的方法详解
2019/10/10 PHP
jQuery 判断页面元素是否存在的代码
2009/08/14 Javascript
js获取单选框或复选框值及操作
2012/12/18 Javascript
如何动态的导入js文件具体该怎么实现
2014/01/14 Javascript
解决json日期格式问题的3种方法
2014/02/02 Javascript
javascript操作excel生成报表全攻略
2014/05/04 Javascript
javascript arguments使用示例
2014/12/16 Javascript
Javascript实现颜色rgb与16进制转换的方法
2015/04/18 Javascript
JS+CSS实现仿msn风格选项卡效果代码
2015/10/22 Javascript
js判断鼠标位置是否在某个div中的方法
2016/02/26 Javascript
30分钟快速掌握Bootstrap框架
2016/05/24 Javascript
javascript中数组(Array)对象和字符串(String)对象的常用方法总结
2016/12/15 Javascript
Vue 中使用vue2-highcharts实现top功能的示例
2018/03/05 Javascript
[01:13]2015国际邀请赛线下观战现场
2015/08/08 DOTA
[45:25]完美世界DOTA2联赛循环赛 PXG vs IO 第一场 11.06
2020/11/09 DOTA
[04:15]DOTA2-DPC中国联赛 正赛 Ehome vs Aster 选手采访
2021/03/11 DOTA
解决python3捕获cx_oracle抛出的异常错误问题
2018/10/18 Python
在python里从协程返回一个值的示例
2019/02/19 Python
Django实现学员管理系统
2019/02/26 Python
python利用多种方式来统计词频(单词个数)
2019/05/27 Python
django框架model orM使用字典作为参数,保存数据的方法分析
2019/06/24 Python
使用Python快乐学数学Github万星神器Manim简介
2019/08/07 Python
Python参数传递机制传值和传引用原理详解
2020/05/22 Python
SmartBuyGlasses荷兰:购买太阳镜和眼镜
2020/03/16 全球购物
教师应聘自荐信范文
2014/03/14 职场文书
投资意向书
2014/07/30 职场文书
先进教师个人事迹材料
2014/12/15 职场文书
杨善洲电影观后感
2015/06/04 职场文书
2015中学教师个人工作总结
2015/07/22 职场文书
2019年预备党员的思想汇报:加深对党的认知
2019/09/25 职场文书
详解Laravel服务容器的优势
2021/05/29 PHP
Python之matplotlib绘制折线图
2022/04/13 Python