jQuery选择器的工作原理和优化分析


Posted in Javascript onJuly 25, 2011

每次申明一个jQuery对象的时候,返回的是jQuery.prototype.init 对象,很多人就会不明白,init明明是jQuery.fn的方法啊,实际上这里不是方法,而是init的构造函数,因为js的prototype对象可 以实现继承,加上js的对象只是引用不会是拷贝,new jQuery,new jQuery.fn和new jQuery.fn.init的子对象是一样的,只是有没有执行到init的不同,这里就不讲原因了,等下一篇再讲为什么会是这样。
当我们使用选择器的时候$(selector,content),就会执行 init(selectot,content),我们看看inti中是怎样执行的:

if ( typeof selector == "string" ) { 
//正则匹配,看是不是HTML代码或者是#id 
var match = quickExpr.exec( selector ); 
//没有作为待查找的 DOM 元素集、文档或 jQuery 对象。 
//selector是#id的形式 
if ( match && (match[1] || !context) ) { 
// HANDLE: $(html) -> $(array) 
//HTML代码,调用clean补全HTML代码 
if ( match[1] ){ 
selector = jQuery.clean( [ match[1] ], context ); 
} 
// 是: $("#id") 
else { 
//判断id的Dom是不是加载完成 
var elem = document.getElementById( match[3] ); 
if ( elem ){ 
if ( elem.id != match[3] ) 
return jQuery().find( selector ); 
return jQuery( elem );//执行完毕return 
} 
selector = []; 
} 
//非id的形式.在context中或者是全文查找 
} else{ 
return jQuery( context ).find( selector ); 
} 
}

这里就说明只有选择器写成$(‘#id')的时候最快,相当于执行了一次 getElementById,后边的程序就不用再执行了。当然往往我们需要的选择器并不是这么简单,比如我们需要id下的CSS为className, 有这样的写法$(‘#id.className')和$(‘#id').find(‘.className');这两种写法的执行结果都是一样的,比 如<div id=”id”><span class=”className”></span></div>,返回的肯定都是<span class=”className”></span>,但是执行的效率是完全不一样的。
在分析一下上边的代码,如果不是$(‘#id')这样的简单选择器的话,都会执行find函 数,那我们再看看find到底是做用的:
find: function( selector ) { 
//在当前的对象中查找 
var elems = jQuery.map(this, function(elem){ 
return jQuery.find( selector, elem ); 
}); 
//下边的代码可以忽略,只是做一些处理 
//这里应用了js的正则对象的静态方法test 
//indexOf("..")需要了解一下xpath的语法,就是判断selector中包含父节点的写法 
//本意就是过滤数组的重复元素 
return this.pushStack( /[^+>] [^+>]/.test( selector ) || selector.indexOf("..") > -1 ? 
jQuery.unique( elems ) : 
elems ); 
}

如果这样写$(‘#id .className'),就会执行到扩展的find(‘#id .className',document),因为当前的this是document的jQuery数组,那我们在看看扩展的find他的实现,代码比较 多,就不列出来,总之就是从第二个参数传递进行的dom第一个子节点开始找,遇见#比对id,遇见.比对ClassName,还有:<+-等处理。 那我们要优化,是不是就要想办法让第二个参数context的范围最小,那样遍历是不是就很少了?
如果我们这样写$(‘#id').find(‘.className'),那程序只这样执行 的,第一次init的时候执行一步getElementById,就return了,接着执行 find(‘.className',divDocument),divDocument就是我们第一次选择的是div标签,如果document下有很 多dom对象的时候,这次只遍历divDocument是不是少了很多次,而且在第一次选择id的速度也要比遍历快的多。
现在大家应该是明白了吧。就是说第一层选择最好是ID,而是简单选择器,目的就是定义范围, 提高速度,这次就说这些,选择写法的优化,其他的优化,下次再说。
Javascript 相关文章推荐
js判断变量是否空值的代码
Oct 26 Javascript
JavaScript 对象、函数和继承
Jul 07 Javascript
JS onmousemove鼠标移动坐标接龙DIV效果实例
Dec 16 Javascript
浅谈JavaScript Date日期和时间对象
Dec 29 Javascript
详解JavaScript基本类型和引用类型
Dec 09 Javascript
AngularJS入门心得之directive和controller通信过程
Jan 25 Javascript
Bootstrap 3的box-sizing样式导致UEditor控件的图片无法正常缩放的解决方案
Sep 15 Javascript
详解Vue监听数据变化原理
Mar 08 Javascript
JavaScript常用工具方法封装
Feb 12 Javascript
vue项目中定义全局变量、函数的几种方法
Nov 08 Javascript
详解vue中使用transition和animation的实例代码
Dec 12 Vue.js
如何理解Vue简单状态管理之store模式
May 15 Vue.js
Jquery 点击按钮显示和隐藏层的代码
Jul 25 #Javascript
multiSteps 基于Jquery的多步骤滑动切换插件
Jul 22 #Javascript
JavaScript实现页面滚动图片加载(仿lazyload效果)
Jul 22 #Javascript
JS 自定义带默认值的函数
Jul 21 #Javascript
表单切换,用回车键替换Tab健(不支持IE)
Jul 20 #Javascript
在浏览器中获取当前执行的脚本文件名的代码
Jul 19 #Javascript
iframe 异步加载技术及性能分析
Jul 19 #Javascript
You might like
PHP编码规范-php coding standard
2007/03/16 PHP
PHP依赖注入原理与用法分析
2018/08/21 PHP
centos7上编译安装php7以php-fpm方式连接apache
2018/11/08 PHP
PHP中检查isset()和!empty()函数的必要性
2019/02/13 PHP
js中的window.open返回object的错误的解决方法
2009/08/15 Javascript
jquery组件使用中遇到的问题整理及解决
2014/02/21 Javascript
node.js中的path.sep方法使用说明
2014/12/08 Javascript
JavaScript中的全局对象介绍
2015/01/01 Javascript
jquery实现浮动在网页右下角的彩票开奖公告窗口代码
2015/09/04 Javascript
javascript实现Email邮件显示与删除功能
2015/11/21 Javascript
H5移动端图片压缩上传开发流程
2016/11/09 Javascript
AngularJS动态菜单操作指令
2017/04/25 Javascript
ES6中新增的Object.assign()方法详解
2017/09/22 Javascript
微信小程序之蓝牙的链接
2017/09/26 Javascript
详解webpack之scss和postcss-loader的配置
2018/01/09 Javascript
通过jquery.cookie.js实现记住用户名、密码登录功能
2018/06/20 jQuery
vue 项目中使用Loading组件的示例代码
2018/08/31 Javascript
NodeJs操作MongoDB教程之分页功能以及常见问题
2019/04/09 NodeJs
JS实现网站楼层导航效果代码实例
2020/06/16 Javascript
[52:32]完美世界DOTA2联赛PWL S2 Magma vs LBZS 第三场 11.18
2020/11/18 DOTA
python编程实现归并排序
2017/04/14 Python
利用Python+Java调用Shell脚本时的死锁陷阱详解
2018/01/24 Python
Python脚本利用adb进行手机控制的方法
2019/07/08 Python
Python(PyS60)实现简单语音整点报时
2019/11/18 Python
Pycharm中Python环境配置常见问题解析
2020/01/16 Python
Python3操作YAML文件格式方法解析
2020/04/10 Python
美国猫狗药物和用品网站:PetCareRx
2017/01/05 全球购物
得到Class的三个过程是什么
2012/08/10 面试题
给医务人员表扬信
2014/01/12 职场文书
外语系毕业生求职自荐信
2014/04/12 职场文书
文明生主要事迹
2014/05/25 职场文书
本科应届生自荐信
2014/06/29 职场文书
2014物价局民主生活会对照检查材料思想汇报
2014/09/24 职场文书
2015年劳动部工作总结
2015/05/23 职场文书
销售人员管理制度
2015/08/06 职场文书
Redis高并发防止秒杀超卖实战源码解决方案
2021/11/01 Redis