Prototype源码浅析 String部分(一)之有关indexOf优化


Posted in Javascript onJanuary 15, 2012

添加到String.prototype中的方法比较多,不过归结起来,大致分为下面几类:

分类 方法名 
原始能力增强               strip |  include  |  startsWith  |  endsWith |  empty |  blank
格式 camelize | capitalize |  underscore |  dasherize  | inspect          
变形 toArray |  succ  | times
替换 interpolate  | sub |  scan |  truncate | gsub
HTML处理 stripTags  | escapeHTML |  unescapeHTML
参数序列化 toQueryParams
JSON处理 unfilterJSON |  isJSON |  evalJSON |  parseJSON
脚本处理 stripScripts |  extractScripts  | evalScripts

从基本的原始能力增强开始,下面是具体的实现,这一段很好理解的:

(function(s){ 
function strip(){ 
return this.replace(/^\s+/,'').replace(/\s+$/,''); 
} 
function include(pattern){ 
return this.indexOf(pattern) > -1;//split 
} 
function startsWith(pattern) { 
return this.lastIndexOf(pattern, 0) === 0; 
} 
function endsWith(pattern) { 
var d = this.length - pattern.length; 
return d >= 0 && this.indexOf(pattern, d) === d; 
} 
function empty() { 
return this == ''; 
} 
function blank() { 
return /^\s*$/.test(this); 
} 
s.strip = String.prototype.trim || strip; 
s.include = include; 
s.startsWith = startsWith; 
s.endsWith = endsWith; 
s.empty = empty; 
s.blank = blank; 
})(String.prototype);

上面的strip在jquery里面是$.trim,而且大部分貌似都是trim。这里直接扩展原生原型的悲剧之处就显现出来了,因为后面的JS实现中(比如chrome)就实现了trim方法,那就弄巧成拙了。
function strip(){ 
return this.replace(/^\s+/,'').replace(/\s+$/,''); 
}

这里面的replace(/^\s+/,'')就是trimLeft,replace(/\s+$/,'')是trimRight,不过Prototype.String中没有这两个方法。

下面是这一部分比较有意思的地方:

当时看这段的时候,对其中的startsWith和endsWith甚是不解,按理来说,startsWith用indexOf就可以了,这里却是用的lastIndexOf。后来去翻了一下Prototype1.6版本的实现:

function startsWith(pattern) { 
return this.indexOf(pattern) === 0; 
} function endsWith(pattern) { 
var d = this.length - pattern.length; 
return d >= 0 && this.lastIndexOf(pattern) === d; 
}

可见,以前版本中startsWith用的就是indexOf,不过1.7版本修改了startsWith的实现。在1.7版本中:

startsWith实现中lastIndexOf从后向前查找,不过起点(fromindex)设置为0,因此,只需要检测开头一次就可以了。
endsWith实现中indexOf从前向后查找,由于字符串长度不定,因此这里计算了一下长度,然后再确定了起点(fromindex),因此也只需要检测结尾一次就可以了。

这里的性能优化之处在于,1.6的实现中,如果开头没有匹配(就是startsWith不成立),但是indexOf依旧会向后查找,直到找到一个匹配的或者字符串结尾,这样就浪费了。举个例子,对于下面的一个操作:

'abcdefgabcdefg'.startsWith('abc')
在1.6版本和1.7版本的实现中,没有任何区别,但是我们转换一下:

'abcdefgabcdefg'.startsWith('xesam')
在1.6实现中,startsWith内部的indexOf操作会在开头的a没有和x匹配后,虽然没有必要再继续了,但是indexOf依旧会继续向后查找,直到找到匹配的‘xesam'或者字符串末尾。
在1.7实现中,startsWith内部的lastIndexOf是反向查找的(fromIndex=0),因此在开头的a没有和x匹配后,操作就停止了,因为lastIndexOf已经到头了。
这么一对比,如果待检测的字符串非常长的话,两种实现方式的效率会有明显的区别。
endsWith的原理也是一样的。

Javascript 相关文章推荐
JavaScript入门教程(12) js对象化编程
Jan 31 Javascript
jQuery温习篇 强大的JQuery选择器
Apr 24 Javascript
ASP.NET中基于JQUERY的高性能的TreeView补充
Feb 23 Javascript
关于jquery中全局函数each使用介绍
Dec 10 Javascript
js实现从右向左缓缓浮出网页浮动层广告的方法
May 09 Javascript
使用coffeescript编写node.js项目的方法汇总
Aug 05 Javascript
javascript跨域的方法汇总
Oct 23 Javascript
assert()函数用法总结(推荐)
Jan 25 Javascript
微信小程序实现流程进度的图样式功能
Jan 16 Javascript
Vue项目中使用better-scroll实现一个轮播图自动播放功能
Dec 03 Javascript
laypage.js分页插件使用方法详解
Jul 27 Javascript
VUE中使用HTTP库Axios方法详解
Feb 05 Javascript
用js小类库获取浏览器的高度和宽度信息
Jan 15 #Javascript
javascript 文本框水印/占位符(watermark/placeholder)实现方法
Jan 15 #Javascript
jQuery-Easyui 1.2 实现多层菜单效果的代码
Jan 13 #Javascript
20个最新的jQuery插件
Jan 13 #Javascript
JSON 数据格式介绍
Jan 13 #Javascript
ASP.NET jQuery 实例6 (实现CheckBoxList成员全选或全取消)
Jan 13 #Javascript
ASP.NET jQuery 实例5 (显示CheckBoxList成员选中的内容)
Jan 13 #Javascript
You might like
《PHP边学边教》(04.编写简易的通讯录――视频教程1)
2006/12/13 PHP
PHP JSON 数据解析代码
2010/05/26 PHP
优化php效率,提高php性能的一些方法
2011/03/24 PHP
单台服务器的PHP进程之间实现共享内存的方法
2014/06/13 PHP
php中实现可以返回多个值的函数实例
2015/03/21 PHP
PHP消息队列用法实例分析
2016/02/12 PHP
yii2.0整合阿里云oss上传单个文件的示例
2017/09/19 PHP
JS(jQuery)实现聊天接收到消息语言自动提醒功能详解【提示“您有新的消息请注意查收”】
2019/04/16 PHP
java解析json方法总结
2019/05/16 PHP
JS Excel读取和写入操作(模板操作)实现代码
2010/04/11 Javascript
23个Javascript弹出窗口特效整理
2011/02/25 Javascript
深入理解JavaScript系列(46):代码复用模式(推荐篇)详解
2015/03/04 Javascript
JavaSciprt中处理字符串之sup()方法的使用教程
2015/06/08 Javascript
js数组去重的方法汇总
2015/07/29 Javascript
用iframe实现不刷新整个页面上传图片的实例
2016/11/18 Javascript
Bootstrap CSS组件之导航(nav)
2016/12/17 Javascript
JavaScript使用简单正则表达式的数据验证功能示例
2017/01/13 Javascript
node.js中实现kindEditor图片上传功能的方法教程
2017/04/26 Javascript
webpack中CommonsChunkPlugin详细教程(小结)
2017/11/09 Javascript
玩转Koa之核心原理分析
2018/12/29 Javascript
Vue 中如何正确引入第三方模块的方法步骤
2019/05/05 Javascript
Vue 实现显示/隐藏层的思路(加全局点击事件)
2019/12/31 Javascript
如何在JavaScript中正确处理变量
2020/12/25 Javascript
[03:56]DOTA2完美大师赛趣味视频之小鸽子和Mineski打台球
2017/11/24 DOTA
使用Python编写基于DHT协议的BT资源爬虫
2016/03/19 Python
详解python持久化文件读写
2019/04/06 Python
Django框架登录加上验证码校验实现验证功能示例
2019/05/23 Python
解决pycharm同一目录下无法import其他文件
2020/02/12 Python
英国时尚服饰电商:Boohoo
2017/10/12 全球购物
Mamaearth官方网站:印度母婴护理产品公司
2019/10/06 全球购物
财务会计专业毕业生自荐信
2013/10/19 职场文书
学生打架检讨书大全
2014/01/23 职场文书
奥林匹克的口号
2014/06/13 职场文书
小学生运动会报道稿
2014/09/12 职场文书
TensorFlow的自动求导原理分析
2021/05/26 Python
R9700摩机记
2022/04/05 无线电