分享更有价值
被信任是一种快乐

jQuery 2.0.3如何用源码分析Sizzle引擎

文章页正文上

本篇文章给大家分享的是有关jQuery 2.0.3如何用源码分析Sizzle引擎,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。什么是JavaScript的“预编译”?按理说,两个签名完全相同的函数,在其他编程语言中应该是非法的。但在JavaScript中,这没错。不过,程序运行之后却发现一个奇怪的现象:两次调用都只是***那个函数里输出的值!显然***个函数没有起到任何作用。这又是为什么呢?JavaScript执行引擎并非一行一行地分析和执行程序,而是一段一段地进行预编译后让后 再执行的。而且,在同一段程序中,函数 在被执行之前 会被预定义,后定定义的 同名函数 会覆盖 先定义的函数。在调用函数的时候,只会调用后一个预定义的函数(因为后一个预定义的函数把前一个预定义的函数覆盖了)。也就是说,在***次调用myfunc之前,***个函数语句定义的代码逻辑,已被第二个函数定义语句覆盖了。所以,两次都调用都是执行***一个函数逻辑了。我们用实际证明下:一段代码中的定义式函数语句会优先执行,这似乎有点象静态语言的编译概念。所以,这一特征也被有些人称为:JavaScript的“预编译”所以总结下:JS 解析器在执行语句前会将函数声明和变量定义进行”预编译”,而这个”预编译”,并非一个页面一个页面地”预编译”,而是一段一段地预编译,所谓的段就是一 个 那么我们再来看看什么是编译函数?这个概念呢,我只用自己的语言表述下吧,先看看我在实际项目中的一种使用吧~这里大概介绍下,偶做的是phonegap项目,基本实现了一套ppt的模板动画PPT的的功能设置(支持生成3个平台的应用)通过这个PPT直接描述出用户行为的数据,然后直接打包生成相对应的实现应用了,实现部分是JS+CSS3+html5 ,关键是可以跨平台哦PC上的效果页面的元素都是动态的可运行可以交互的编译出来的的APK通过一套PPT软件生成的,页面有大量的动画,声音,视频,路径动画,交互,拖动 等等效果,这里不细说了,那么我引入编译函数这个概念我是用来干什么事呢?一套大的体系,流程控制是非常重要的,简单的来说呢就是在某个阶段该干哪一件事件了但是JS呢其实就是一套异步编程的模型编写异步代码是时常的事,比如有常见的异步操作:Ajax(XMLHttpRequest)Image Tag,Script Tag,iframe(原理类似)setTimeout/setIntervalCSS3 Transition/AnimationHTML5 Web DatabasepostMessageWeb WorkersWeb Socketsand more…JavaScript是一门单线程语言,因此一旦有某个API阻塞了当前线程,就相当于阻塞了整个程序,所以“异步”在JavaScript编程中占有很重要的地位。异步编程对程序执行效果的好处这里就不多谈了,但是异步编程对于开发者来说十分麻烦,它会将程序逻辑拆分地支离破碎,语义完全丢失。因此,许多程序员都在打造一些异步编程模型已经相关的API来简化异步编程工作,例如Promise模型现在有的异步流程控制大多是基于CommonJS Promises规范,比如 jsdeferred,jQuery自己的deferred等等从用户角度来说呢,越是功能强大的库,则往往意味着更多的API,以及更多的学习时间,这样开发者才能根据自身需求选择最合适的方法从开发者角度,API的粒度问题,粒度越大的API往往功能越强,可以通过少量的调用完成大量工作,但粒度大往往意味着难以复用。越细粒度的API灵活度往往越高,可以通过有限的API组合出足够的灵活性,但组合是需要付出“表现力”作为成本的。JavaScript在表现力方面有一些硬伤。好像这里有点偏题了,总的来说呢,各种异步编程模型都是种抽象,它们是为了实现一些常用的异步编程免费云主机、域名模式而设计出来的一套有针对性的API。但是,在实际使用过程中我们可能遇到千变万化的问题,一旦遇到模型没有“正面应对”的场景,或是触及这种模型的限制,开发人员往往就只能使用一些相对较为丑陋的方式来“回避问题”那么在我们实际的开发中呢,我们用JS表达一段逻辑,由于在各种环境上存在着各种不同的异步情景,代码执行流程会在这里“暂停”,等待该异步操作结束,然后再继续执行后续代码如果是这样的情况这段代码很简单,但是结果确不是我们想要的,我们修改一下任何一个普通的JavaScript程序员都能顺利理解这段代码的含义,这里的“回调”并不是“阻塞”,而会空出执行线程,直至操作完成。而且,假如系统本身没有提供阻塞的API,我们甚至没有“阻塞”代码的方法(当然,本就不该阻塞)。到底编译函数这个概念是干嘛?JavaScript是单线程的,代码也是同步从上向下执行的,执行流程不会随便地暂停,当遇到异步的情况,从而改变了整个执行流程的时候,我们需要对代码进行自动改写,也就是在程序的执行过程中动态生成并执行新的代码,这个过程我想称之为编译函数的一种运用吧.我个人理解嘛,这里只是一个概念而已,闭包的一种表现方式,就像MVVM的angular就搞出一堆的概念,什么HTML编译器,指令,表达式,依赖注入等等,当然是跟Javaer有关系…这里回到我之前的项目上面,我个人引入这个编译函数,是为了解决在流程中某个环节中因为异步导致的整个流程的执行出错,所以在JS异步之后,我会把整个同步代码编译成一个闭包函数,因为这样可以保留整个作用域的访问,这样等异步处理完毕之后,直接调用这个编译函数进行匹配即可,这样在异步的阶段,同步的代码也同时被处理了其实说白了,就是一种闭包的使用,只是在不同的场景中换了一个优雅的词汇罢了, 那么在sizzle中,引入这个编译函数是解决什么问题了?sizzle编译函数文章开头就提到了,sizzle引入这个实现主要的作用是分词的筛选,提高逐个匹配的效率这里接着上一章节解析原理我们在经过词法分析,简单过滤,找到适合的种子集合之后最终的选择器抽出了input这个种子合集seed重组的选择器selector还有词法分析合集groupSizzle中的元匹配器通过tokenize最终分类出来的group分别都有对应的几种type每一种type都会有对应的处理方法可以把“元”理解为“原子”,也就是最小的那个匹配器。每条选择器规则最小的几个单元可以划分为:ATTR | CHILD | CLASS | ID | PSEUDO | TAG
在Sizzle里边有一些工厂方法用来生成对应的这些元匹配器,它就是Expr.filter。
举2个例子(ID类型的匹配器由Expr.filter[“ID”]生成,应该是判断elem的id属性跟目标属性是否一致),拿出2个源码到这里应该想到Sizzle其实是不是就是通过对selector做“分词”,打散之后再分别从Expr.filter 里面去找对应的方法来执行具体的查询或者过滤的操作?答案基本是肯定的但是这样常规的做法逻辑上是OK的,但是效率如何?所以Sizzle有更具体和巧妙的做法Sizzle在这里引入了编译函数的概念通过Sizzle.compile方法内部的,matcherFromTokens matcherFromGroupMatchers把分析关系表,生成用于匹配单个选择器群组的函数matcherFromTokens,它充当了selector“分词”与Expr中定义的匹配方法的串联与纽带的作用,可以说选择符的各种排列组合都是能适应的了。Sizzle巧妙的就是它没有直接将拿到的“分词”结果与Expr中的方法逐个匹配逐个执行,而是先根据规则组合出一个大的匹配方法,***一步执行我们看看如何用matcherFromTokens来生成对应Token的匹配器?先贴源码Sizzle.compilematcherFromTokens重点就是cached 的结果就是matcherFromTokens返回的matchers编译函数了matcherFromTokens的分解是有规律的:语义节点+关系选择器的组合Expr.relative 匹配关系选择器类型当遇到关系选择器时elementMatcher函数将matchers数组中的函数生成一个函数在递归分解tokens中的词法元素时提出***个typ匹配到对应的处理方法matcher其实最终结果返回的就是bool值,但是这里返回只是一个闭包函数,不会马上执行,这个过程换句话就是 编译成一个匿名函数继续往下分解如果遇到关系选着符就会合并分组了通过elementMatcher生成一个***匹配器看代码大概就知道,就是分解这个子匹配器了,返回又一个curry函数,给addCombinator方法matcher为当前词素前的“匹配器”combinator为位置词素根据关系选择器检查如果是这类没有位置词素的选择器:’#id.aaron[name=”checkbox”]‘从右到左依次看看当前节点elem是否匹配规则即可。但是由于有了位置词素,那么判断的时候就不是简单判断当前节点了,可能需要判断elem的兄弟或者父亲节点是否依次符合规则。这是一个递归深搜的过程。所以matchers又经过一层包装了然后用同样的方式递归下去,直接到tokens分解完毕返回的结果一个根据关系选择器分组后在组合的嵌套很深的闭包函数了看看结构但是组合之后怎么执行?superMatcher方法是matcherFromGroupMatchers( elementMatchers, setMatchers )方法return出来的,但是执行起重要作用的是它以上就是jQuery 2.0.3如何用源码分析Sizzle引擎,小编相信有部分知识点可能是我们日常工作会见到或用到的。希望你能通过这篇文章学到更多知识。更多详情敬请关注云技术行业资讯频道。

相关推荐: vue如何使用vue-loader

这篇文章主要介绍vue如何使用vue-loader,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!vue-loader小技巧vue-loader 是处理 *.vue 文件的 webpack loader。它本身提供了丰富的 API,有些 …

文章页内容下
赞(0) 打赏
版权声明:本站采用知识共享、学习交流,不允许用于商业用途;文章由发布者自行承担一切责任,与本站无关。
文章页正文下
文章页评论上

云服务器、web空间可免费试用

宝塔面板主机、支持php,mysql等,SSL部署;安全高速企业专供99.999%稳定,另有高防主机、不限制内容等类型,具体可咨询QQ:360163164,Tel同微信:18905205712

主机选购导航云服务器试用

登录

找回密码

注册