Mini,又个 Javascript 选择器(2)
作者:手气不错 来源:gracecode.com 发布时间:2009-10-06 14:48:00
简单至上
Mini 的代码很简单,甚至不用恐惧于如何去读懂 Sizzle 这样的每行源代码。先从它的调用函数 _find 看起,往下阅读几行,你就发现它性能的秘密
if (!simple && context.querySelectorAll) { return realArray(context.querySelectorAll(selector));}
很多的现代浏览器(包括 Gecko、WebKit 等)都 提供了原生的 Javascript 选择器支持。 Mini 充分得利用了这点,从而将大部分的工作交给了浏览器(也免除了日后的维护之忧)。这点非常值得称道, 也是我们以后写 Javascript 应该走的方向 -- 要基于浏览器提供的功能而非类型进行对应的开发。
_find 其后的逻辑非常的简单,使用几个正则将提供的选择器解析出来,分别根据 getElementsByClassName、 getElementsByClassName 以及 getElementById 获取节点。
继续根据上面的思路,由于陈旧的 IE 没有既没有提供 querySelectorAll 也没有提供 getElementsByClassName, 那么它只能走到 else 的尽头,使用 filterByAttr 函数。
取到对应 className 以及 tagName 后,还得根据选择器获取其与其相符的节点,那么就轮到 filterParents 干活了。
filterParents 这个函数也是相对 _find 比较核心的函数,而且也是主要的性能消耗点。filterParents 其实要做的和 _find 类似,唯一不同的是它根据关系符向上剔除未满足条件的节点。
通过上面两个函数所得到的节点,通常已经是满足选择符条件的节点了。 但是可能的情况就是有重复的节点,这时就该 unique 函数上场,顾名思义剔除重复的节点。
这里要提到的就是 unique 函数做了个简单的 memoization 实现, 作者的用心可谓从细节方面体现得淋漓尽致。还有个小技巧就是
var uid = +new Date();
竟然可以用这样直接返回时间戳,俏皮的代码让人再次感到犹如嚼了口薄荷糖,非常的清新(好吧,我火星了)。
读码到最后,有一点思考就是为何每次都要使用 realArray 函数强制将 NodeList 转换成 Array?虽然使用 querySelectorAll 返回的是 NodeList ,但是也是可以使用 Array 操作迭代。作者这样的做法我推测,可能是出于返回数据类型一致的缘故。
观点
说说到我的个人观点,这可能会让这篇文章前后矛盾。Javascript 选择器(selector engine)我个人不是非常推荐使用。
原因主要有两点,其一就是性能,其二就是会让写出来的代码过于的依赖于 DOM 结构。但能读到如 Mini 这样的代码,窥其内部运作机制,未尝不是件非常让人愉悦的事情。
最后,说说 Mini 的作者 James Padolsey 。我本人也很难相信,他竟然只有 19 岁!更难 得的是在他 Blog 上的 About me 页面中写道
What services do I currently offer?- Everything JavaScript!
同时,他也是 jQuery Cookbook 的作者。 “小小年纪”能够有这样的心态以及成就,让我们这帮“前端老古董”感到唏嘘不已 :^)


猜你喜欢
- 安装报错类型,解决方案;1. 数据库连接报错mysqldb只支持python2,pymysql支持3,都是使用c写的驱动,性能更好# dja
- 今天在打开sql server 的时候打不开。报了一个错误,然后我打开sql server配置管理器,就看到了如下图这个错误。然后就去网上搜
- 起因:有一批数据需要每个月进行分析,数据存储在excel中,行标题一致,需要横向合并进行分析。数据示意:具有多个代码:# -*- codin
- 本文实例讲述了Python Django框架单元测试之文件上传测试。分享给大家供大家参考,具体如下:Submitting files is
- 本文实例讲述了python简单读取大文件的方法。分享给大家供大家参考,具体如下:Python读取大文件(GB级别)采用的办法很简单:with
- 这篇文章主要介绍了Python异常继承关系和自定义异常实现代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价
- 本文实例讲述了Python常见MongoDB数据库操作。分享给大家供大家参考,具体如下:MongoDB 是一个基于分布式文件存储的数据库。由
- 4. 生成器(generator)4.1. 生成器简介首先请确信,生成器就是一种迭代器。生成器拥有next方法并且行为与迭代器完全相同,这意
- 近期,一直在研究MySQL数据库,经常修改配置文件,导致MySQL数据库无法使用,不得不反复重装MySQL数据库。以下是在Windows7
- 本文实例讲述了Python基础之函数基本用法与进阶。分享给大家供大家参考,具体如下:目标函数参数和返回值的作用函数的返回值 进阶函数的参数
- 自动求导机制从后向中排除子图每个变量都有两个标志:requires_grad和volatile。它们都允许从梯度计算中精细地排除子图,并可以
- 如何去读取一个没有表头的二维csv文件(如下图所示)?并以元组的形式表现数据:((1.0, 0.0, 3.0, 180.0), (2.0,
- 前言这篇文章主要介绍了Python 字符串去除空格的6种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,来
- 1.参考Beautiful Soup and Unicode Problems详细解释unicodedata.normalize('
- 背景在校园里认证上网很麻烦需要web输入账号密码有时还会忘记web地址此时就需要一个人或者程序帮我们实现,这时我想到用python制作这个程
- 同时装配两个相同类型数据库1.配置文件:spring: profiles: active: devda
- 我们先看一下淘宝的页面:这么一个庞然大物,该怎么切图呢?显然按照给出的方法也可以完成这项任务,但是做为前端开发的我们是否应该给自己提出更高的
- select count(*) as lot from OA_sample_check where left(ecnNO, LOCATE(&
- 给定list,如何以空格/逗号等符号以分隔符输出呢?一般的,简单的for循环可以打印出list的内容:l=[1,2,3,4]for i in
- Golang可以通过断言,判断值的类型s:="hello world"i:=interface{}(s)//将数值转化为