jQuery源码学习(版本1.11)-Sizzle代码架构及整体匹配流程

代码分段

对Sizzle代码进行分段,可以得到如下整体架构(括号内代表在jQuery1.11.1.js文件中的具体行号):
var Sizzle =
(function( window ) {

	(598, 711) // 定义Sizzle内部使用的变量(多为正则和引用原生对象方法)
	
	(773, 880) // function Sizzle()  定义Sizzle函数,同时也作为命名空间,最终返回
	
	(888, 1026) // 内部使用的function
	
	(1029, 1408) // 定义support = Sizzle.support,isXML = Sizzle.isXML,setDocument = Sizzle.setDocument
				 // 其中setDocument方法,初始化了Sizzle内部使用的多个变量
				 
	(1410, 1542) // 定义Sizzle.matches,Sizzle.matchesSelector,Sizzle.contains,Sizzle.attr,Sizzle.error,Sizzle.uniqueSort,getText = Sizzle.getText
	
	(1544, 2023) // Expr = Sizzle.selectors,Sizzle的过滤器,用于根据分割后的块表达式对候选集进行过滤
	
	(2025, 2090) // tokenize = Sizzle.tokenize,Sizzle的分割器,用于分割选择器表达式
	
	(2092, 2444) // 内部使用的function
	
	(2446, 2474) // compile = Sizzle.compile,也是用于分割选择器表达式,内部调用了tokenize并缓存,tokenize相当于是分割器的实现,compile则是在外面包装了一层
	
	(2485, 2553) // select = Sizzle.select,Sizzle查找的入口方法
	
	(2558, 2616) // 一些浏览器兼容性设置

return Sizzle;

})( window );
跟jQuery架构相同,同样是闭包自执行,最终返回命名空间供外层作用域使用。

代码工作流程简析

1.现代浏览器都支持Element的querySelectorAll方法,Sizzle也使用了,因此,一般情况下,$(selector)进入function Sizzle()后,会首先使用querySelectorAll,得到返回值返回。
2.其他无法使用querySelectorAll的情况下,会进入Sizzle自己的select方法,select调用compile,compile调用tokenize将复杂的选择器表达式分割,得到块表达式,然后compile再通过其他内部方法,使用Expr过滤器,得到返回值
3.表达式分割器,最终会将选择器表达式分割成数组,如果存在逗号","即并列选择器,则为两层数组,第一层存放分割并列选择器后的数组,第二层数组存放块表达式(即可直接用原生方法查找的最小表达式,如id,tag,class,name等,以及四个关系表达式"+",">","~"," ");如果没有并列选择器,则一层数组存放块表达式。
4.Sizzle的查找一般情况下为从右往左查找,特殊情况如存在“:first”,“last”等需要先确定左边候选集范围时,才使用从左往右。对于哪些情况需要从左往右,Sizzle已经全部列好,保存在matchExpr.needsContext正则下,调用即可判断,默认情况下从右往左。
5.从右往左的性能更佳,原因在于(纯属个人理解),假设是从左往右,遇到父子关系">"或者祖先关系" "连接符时,要对内部所有的子/后代节点进行遍历,而从右向左,先找出子/后代节点,直接一层层判断父亲即可,而通常html文档当中,平铺的并列关系的节点远远多于层次,即,节点数量/层次,是远大于1的整数,最小也是等于1,因此从右往左效率更佳。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值