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 相关文章推荐
比较简单的一个符合web标准的JS调用flash方法
Nov 29 Javascript
用javascript模仿ie的自动完成类似自动完成功的表单
Dec 12 Javascript
JS脚本defer的作用示例介绍
Jan 02 Javascript
js实现网页抽奖实例
Aug 05 Javascript
解决JS请求服务器gbk文件乱码的问题
Oct 16 Javascript
jQuery给表格添加分页效果
Mar 02 Javascript
浅谈vue项目重构技术要点和总结
Jan 23 Javascript
vue中实现先请求数据再渲染dom分享
Mar 17 Javascript
jquery ajaxfileuplod 上传文件 essyui laoding 效果【防止重复上传文件】
May 26 jQuery
微信小程序环境下将文件上传到OSS的方法步骤
May 31 Javascript
vue下载二进制流图片操作
Oct 26 Javascript
vue3获取当前路由地址
Feb 18 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代码质量36计
2012/09/05 PHP
在windows服务器开启php的gd库phpinfo中未发现
2013/01/13 PHP
关于php循环跳出的问题
2013/07/01 PHP
保存到桌面、设为桌面且带图标的PHP代码
2013/11/19 PHP
PHP在线调试执行的实现方法(附demo源码)
2016/04/28 PHP
PHP实现会员账号单唯一登录的方法分析
2019/03/07 PHP
JavaScript编程开发中的五个实用小技巧
2010/07/22 Javascript
淘宝网提供的国内NPM镜像简介和使用方法
2014/04/17 Javascript
JQuery给网页更换皮肤的方法
2015/05/30 Javascript
JavaScript实现对下拉列表值进行排序的方法
2015/07/15 Javascript
JavaScript模块规范之AMD规范和CMD规范
2015/10/27 Javascript
js中时间格式化的几种方法
2018/07/22 Javascript
layer.close()关闭进度条和Iframe窗的方法
2018/08/17 Javascript
详解Express笔记之动态渲染HTML(新手入坑)
2018/12/13 Javascript
JavaScript私有变量实例详解
2019/01/24 Javascript
小程序实现订单倒计时功能
2019/04/23 Javascript
详解微信小程序之一键复制到剪切板
2019/04/24 Javascript
vue-router两种模式区别及使用注意事项详解
2019/08/01 Javascript
Vue路由之JWT身份认证的实现方法
2019/08/26 Javascript
vue 组件销毁并重置的实现
2020/01/13 Javascript
深入理解webpack process.env.NODE_ENV配置
2020/02/23 Javascript
Vue实现购物小球抛物线的方法实例
2020/11/22 Vue.js
Python性能优化技巧
2015/03/09 Python
numpy matrix和array的乘和加实例
2018/06/28 Python
python绘制直线的方法
2018/06/30 Python
Python hashlib模块加密过程解析
2019/11/05 Python
Python实现序列化及csv文件读取
2020/01/19 Python
Python2手动安装更新pip过程实例解析
2020/07/16 Python
Fanatics英国官网:美国体育电商
2018/11/06 全球购物
科技开发中心办公室主任岗位责任制
2014/02/10 职场文书
李白故里导游词
2015/02/12 职场文书
2015年社区统计工作总结
2015/04/21 职场文书
创作书写之导游词实用技巧分享(干货)
2019/12/20 职场文书
Python数据分析入门之数据读取与存储
2021/05/13 Python
Tensorflow与RNN、双向LSTM等的踩坑记录及解决
2021/05/31 Python
Android Canvas绘制文字横纵向对齐
2022/06/05 Java/Android