一个人去完成一件事情,如果派多个人去做的话,只要配合默契,效率比一个人做肯定要高,效率提高,所需的时间就减少了。如果只能一个人完成,那么必须设法提高自己的劳动效率,这个提高可以是量的改变也可以是质的改变。我把这个量的改变称为空间上的改变,也就是说空间和时间是可以相互转换的。

按照解析原理与过滤器的原理一次用循环递归去匹配查找,这样的效率是很慢的,那么sizzle从给1.8开始就引入了编译的概念,就是空间换时间的算法通过缓存大量的闭包匹配器从而提高重复的效率

闭包是js的特性,我们经常会用来作为私有变量的保存处理,那么sizzle就很好的利用了这一特性,把选择器中每一个选择原子都变成了函数的处理方法,然后通过闭包保存着。在缓存在内存中去,这样有重复使用的时候就会首先调用缓存。

Sizzle对于编译这个最终的过滤器闭包是非常绕的,先通过简单的例子去展示这个一个复杂的思路。

var filter = {
ATTR: function(name, operator,check) {
return function(elem) {
var attr = elem.getAttribute(name)
if (operator === "=") {
if(attr === check){
return true
}
}
return false;
}
},
TAG: function(nodeNameSelector) {
return function(elem) {
return elem.nodeName && elem.nodeName.toLowerCase() === nodeNameSelector;
};
}
} function addCombinator(matcher) {
return function(elem, context, xml) {
while ((elem = elem['parentNode'])) {
if (elem.nodeType === 1) {
//找到第一个亲密的节点,立马就用终极匹配器判断这个节点是否符合前面的规则
return matcher(elem);
}
}
}
} 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];
} function matcherFromTokens(tokens){
var len = tokens.length;
var matcher, matchers = [];
for (i = 0; i < len; i++) {
if (tokens[i].type === " ") {
matchers = [addCombinator(elementMatcher(matchers), matcher)];
} else {
matcher = filter[tokens[i].type].apply(null, tokens[i].matches);
matchers.push(matcher);
}
}
return elementMatcher(matchers);
} function compile() {
//种子合集
var seed = document.querySelectorAll('input')
//选择器
var selector = "Aaron [name=ttt]";
var elementMatchers = [];
var results = []
var match = [{
matches: ["div"],
type: "TAG",
value: "Aaron"
}, {
type: " ",
value: " "
}, {
matches: ["name", "=", "ttt"],
type: "ATTR",
value: "[name=ttt]"
}]
elementMatchers.push(matcherFromTokens(match));
var matcher, elem;
for (var i = 0; i < seed.length; i++) {
matcher = elementMatchers[0];
var elem = seed[i];
if (matcher(elem)) {
results.push(elem);
break;
}
}
console.log(results)
} compile();

抛开伪类的处理,这里就是一个简化版的sizzle的流程

测试,高级浏览器

参考对照学习

Sizzle


sizzle编译函数的更多相关文章

  1. jQuery 2.0.3 源码分析Sizzle引擎 - 编译函数(大篇幅)

    声明:本文为原创文章,如需转载,请注明来源并保留原文链接Aaron,谢谢! 从Sizzle1.8开始,这是Sizzle的分界线了,引入了编译函数机制 网上基本没有资料细说这个东东的,sizzle引入这 ...

  2. jQuery1.11源码分析(4)-----Sizzle工厂函数[原创]

    在用前两篇讲述完正则表达式.初始化.特性检测之后,终于到了我们的正餐——Sizzle工厂函数! Sizzle工厂函数有四个参数, selector:选择符 context:查找上下文 results: ...

  3. Python中动态编译函数compile(source, filename, mode, ......)参数filename的作用是什么?

    动态编译函数compile调用语法如下: compile(source, filename, mode, flags=0, dont_inherit=False, optimize=-1) 其中的fi ...

  4. jQuery1.11源码分析(5)-----Sizzle编译和过滤阶段[原创]

    在上一章中,我们说到在之前的查找阶段我们已经获得了待选集seed,那么这一章我们就来讲如何将seed待选集过滤,以获得我们最终要用的元素. 其实思路本质上还是不停地根据token过滤,但compile ...

  5. 通过编译函数库来学习GCC【转】

    转自:http://blog.csdn.net/u012365926/article/details/51446295 基本概念 什么是库 在windows平台和linux平台下都大量存在着库. 本质 ...

  6. python预编译函数compile,exec,eval

    funcname = "func" func = "def %s():\n" % funcname funccontent = 'print "hel ...

  7. jQuery-1.9.1源码分析系列(三) Sizzle选择器引擎——编译原理

    这一节要分析的东东比较复杂,篇幅会比较大,也不知道我描述后能不能让人看明白.这部分的源码我第一次看的时候也比较吃力,现在重头看一遍,再分析一遍,看能否查缺补漏. 看这一部分的源码需要有一个完整的概念后 ...

  8. JS数据类型及函数的预编译

    1.JS总体上分为:原始值和引用值 原始值分为:Number.Boolean.String.undefined.null;原始值不可改变的值,存储在栈[stack]的,先进后出! 引用值:array. ...

  9. 深入剖析php执行原理(2):函数的编译

    本文只探讨纯粹的函数,并不包含方法.对于方法,会放到类.对象中一起研究. 想讲清楚在zend vm中,函数如何被正确的编译成op指令.如何发生参数传递.如何模拟调用栈.如何切换作用域等等,的确是一个很 ...

随机推荐

  1. 关于jquery简单操作简单表格

    最近在摸索jquery中,想着学习过程中还是记下点自己的东西比较好,不管是日后自己查阅,亦或是对于他人有些许帮助. 也是一件两全其美的事情了. 下面我就简单 贴上自己的html中重要部分了. 具体实现 ...

  2. 总结30个CSS3选择器(转载)

    或许大家平时总是在用的选择器都是:#id  .class  以及标签选择器.可是这些还远远不够,为了在开发中更加得心应手,本文总结了30个CSS3选择器,希望对大家有所帮助. 1 *:通用选择器 * ...

  3. 深入理解JavaScript运行机制

    深入理解JavaScript运行机制 前言 本文是写作在给团队新人培训之际,所以其实本文的受众是对JavaScript的运行机制不了解或了解起来有困难的小伙伴.也就是说,其实真正的原理和本文阐述的并不 ...

  4. Ubuntu install JDK适合像我的小白

    1.#下载JDK,记住保存的目录 2. sudo mkdir /usr/java 3. sudo tar zxvf jdk-7u75-linux-x64.tar.gz -C /usr/java 4. ...

  5. ceil 模块

    # 有时需要得到一个最小的整数,而这个数只能比自己大或相等,不能小于自己 #如: 2.1 我们需要得到的最小整数为3,即使后一位只有很小的一部分,一般用于分页 from math import cei ...

  6. 【转】你所不知道的Android Studio调试技巧

    这篇写Android studio debug技巧个人觉得写得不错,转自:http://www.jianshu.com/p/011eb88f4e0d# Android Studio目前已经成为开发An ...

  7. 四、jquery中的事件与应用

    当用户浏览页面时,浏览器会对页面代码进行解释或编译--这个过程实质上是通过时间来驱动的,即页面在加载时,执行一个Load事件,在这个事件中实现浏览器编译页面代码的过程.时间无论在页面元素本身还是在元素 ...

  8. JSP实现在项目在网页上查询

    <table> <caption>user</caption> <tr> <td>编号</td> <td>姓名< ...

  9. myeclipse连接数据库sql server

    1.打开数据库Microsoft sql server2008,输入以下命令: 此时可是看到端口号为1619,记住此端口号,等会儿会用到. 2.打开myeclipse2014,找到最上方的myecli ...

  10. 移动端click时间延迟300

    解决移动端click延迟事件方法,,引入fastclick.js  然后在script标签里面写上FastClick.attach(document.body); <!DOCTYPE html& ...