网络编程
位置:首页>> 网络编程>> JavaScript>> Mini,又个 Javascript 选择器(2)

Mini,又个 Javascript 选择器(2)

作者:手气不错 来源:gracecode.com 发布时间:2009-10-06 14:48:00 

标签:mini,选择器,JavaScript

简单至上

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 的作者。 “小小年纪”能够有这样的心态以及成就,让我们这帮“前端老古董”感到唏嘘不已 :^)

0
投稿

猜你喜欢

手机版 网络编程 asp之家 www.aspxhome.com