在return的时候又调用了elementMatcher()函数,返回的结果还是一个函数。上面介绍compile函数时看到过返回的函数结构。
matcherFromTokens函数体中有用到addCombinator()和elementMatcher()函数以及filter对象。先看filter:
一目了然,一看就知道filter中的ATTR和TAG对应了match分词组中的type类型,所以filter对应了非关系型分词的matcher函数。
addCombinator
function addCombinator(matcher){ return function(elem, context, xml){ while(elem = elem["parentNode"]){ if(elem.nodeType === 1) //找到第一个亲密的节点,立马就用终极匹配器判断这个节点是否符合前面的规则 return matcher(elem); } } } addCombinator对应关系型分词matcher。本例只列举了祖先和子孙关系" "的合并,返回的结果是一个签名为function(elem, contenxt, xml)的函数,函数中elem[“parentNode”]找到文档元素类型的父节点,再调用matcher校验这个父节点是否匹配。
所以关系型matcher函数执行的过程:先通过关系类型找到匹配元素,然后再调用matcher校验匹配结果。
elementMatcher
function elementMatcher(matchers){ return matchers.length > 1 ? function(elem, context, xml){ var i = matchers.length; while(i--){ if(!matchers[i](elem, context, xml)){ return false; } } return true; }: matchers[0]; }elementMatcher()函数就是干实事的家伙,它遍历matchers函数数组,执行每个matcher函数,一旦有matchers[i]返回false则整个匹配就失败了。这里需要注意的一点是i--,为什么是反序遍历?因为JQuery Sizzle匹配的原则是从右往左。由于前面的match数组是按照选择器从左往右保存的,所以这里先执行最后面的。
上面所有的代码只是简单模拟了JQuery Sizzle引擎的执行过程,真实的源代码很复杂,估计只有大神些才能领悟透彻。大神,艾伦得算一个。
说到闭包,如果能把JQuery Sizzle代码分析透彻,理解闭包易如反掌。本篇介绍的函数返回值都是函数,而每个返回函数需要的变量都是通过闭包存储起来,在真正执行函数的时候再读取这些变量。
如果本篇内容对大家有帮助,请点击页面右下角的关注。如果觉得不好,也欢迎拍砖。你们的评价就是博主的动力!下篇内容,敬请期待!
分享到:
关注微信,跟着我们扩展技术视野。每天推送IT新技术文章,每周聚焦一门新技术。微信二维码如下:
微信公众账号:尚学堂(微信号:bjsxt-java)
原文链接:
上一篇
下一篇