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 相关文章推荐
在页面上用action传递参数到后台出现乱码的解决方法
Dec 31 Javascript
JavaScript生成的动态下雨背景效果实现方法
Feb 25 Javascript
js实现绿白相间竖向网页百叶窗动画切换效果
Mar 02 Javascript
解决js函数闭包内存泄露问题的办法
Jan 25 Javascript
浅谈jquery页面初始化的4种方式
Nov 27 Javascript
Vue-resource拦截器判断token失效跳转的实例
Oct 27 Javascript
微信小程序实现图片上传、删除和预览功能的方法
Dec 18 Javascript
angularjs 获取默认选中的单选按钮的value方法
Feb 28 Javascript
JavaScript中click和onclick本质区别与用法分析
Jun 07 Javascript
vue实现底部菜单功能
Jul 24 Javascript
vuex2中使用mapGetters/mapActions报错的解决方法
Oct 20 Javascript
vue-cli3配置favicon.ico和title的流程
Oct 27 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
?生?D片??C字串
2006/12/06 PHP
php使用iconv中文截断问题的解决方法
2015/02/11 PHP
开启PHP的伪静态模式
2015/12/31 PHP
php判断是否连接上网络的方法实例详解
2016/12/14 PHP
javascript 写的一个简单的timer
2009/07/30 Javascript
jQuery实现表单input中提示文字value随鼠标焦点移进移出而显示或隐藏的代码
2010/03/21 Javascript
基于jquery的15款幻灯片插件
2011/04/10 Javascript
JavaScript中“过于”犀利地for/in循环使用示例
2013/10/22 Javascript
网站接入QQ登录的两种方法
2014/07/22 Javascript
jquery马赛克拼接翻转效果代码分享
2015/08/24 Javascript
javascript实现对表格元素进行排序操作
2015/11/18 Javascript
jQuery实现的调整表格行tr上下顺序
2016/01/10 Javascript
解决bootstrap导航栏navbar在IE8上存在缺陷的方法
2016/07/01 Javascript
详解Vue 方法与事件处理器
2017/06/20 Javascript
浅谈Angular4中常用管道
2017/09/27 Javascript
javascript实现5秒倒计时并跳转功能
2019/06/20 Javascript
[59:30]VG vs LGD 2019国际邀请赛淘汰赛 胜者组 BO3 第二场 8.22
2019/09/05 DOTA
复制粘贴功能的Python程序
2008/04/04 Python
如何使用python爬取csdn博客访问量
2016/02/14 Python
Python 的内置字符串方法小结
2016/03/15 Python
python如何实现视频转代码视频
2019/06/17 Python
python从list列表中选出一个数和其对应的坐标方法
2019/07/20 Python
python设置表格边框的具体方法
2020/07/17 Python
Python与C/C++的相互调用案例
2021/03/04 Python
HTML5地理定位与第三方工具百度地图的应用
2016/11/17 HTML / CSS
Shopee越南:东南亚与台湾电商平台
2019/02/03 全球购物
计算机开发个人求职信范文
2013/09/26 职场文书
历史学专业毕业生求职信
2013/09/27 职场文书
自荐信的禁忌和要点
2013/10/15 职场文书
艺术教育实施方案
2014/05/03 职场文书
公务员政审单位鉴定材料
2014/05/16 职场文书
美化环境标语
2014/06/20 职场文书
2015年音乐教学工作总结
2015/07/22 职场文书
2016党员学习作风建设心得体会
2016/01/21 职场文书
Python包管理工具pip的15 个使用小技巧
2021/05/17 Python
Vscode中SSH插件如何远程连接Linux
2022/05/02 Servers