博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
sizzle编译函数
阅读量:6226 次
发布时间:2019-06-21

本文共 2701 字,大约阅读时间需要 9 分钟。

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

按照解析原理与过滤器的原理一次用循环递归去匹配查找,这样的效率是很慢的,那么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的流程

测试,高级浏览器

本文转自艾伦 Aaron博客园博客,原文链接:http://www.cnblogs.com/aaronjs/p/3972490.html,如需转载请自行联系原作者
你可能感兴趣的文章
磁盘配额
查看>>
O-3 WOL网络唤醒详解,随时随地打开电脑
查看>>
F(x)
查看>>
shell脚本整理
查看>>
再续伯努利欧拉错装信封问题
查看>>
可变多维数组组合算法
查看>>
使用Firefox的“HttpRequester”插件测试REST风格的webservice
查看>>
视图和索引
查看>>
论文解读:基于机器学习的知道推荐—Enlister
查看>>
管道命令和xargs的区别
查看>>
百度APP爬虫
查看>>
最全GhostXP SP3系统安装方法(光盘安装|硬盘安装|U盘安装)详细图文教程
查看>>
十七、编辑头像(带参数)
查看>>
U盘数据恢复
查看>>
31个Oracle常用问题及命令
查看>>
输入输出 字符串相关
查看>>
request获取url链接和参数
查看>>
腾讯视频播放器V 1.0 去广告补丁
查看>>
实现本地上传的Kindetitor的Servlet版本
查看>>
Android学习笔记—第九章 Activity的加载模式
查看>>