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 相关文章推荐
取得父标签
Nov 14 Javascript
SUN的《AJAX与J2EE》全文译了
Feb 23 Javascript
JavaScript中的Location地址对象
Jan 16 Javascript
基于jQuery的输入框在光标位置插入内容, 并选中
Oct 29 Javascript
jQuery表格插件ParamQuery简单使用方法示例
Dec 05 Javascript
jQuery中事件对象e的事件冒泡用法示例介绍
Apr 25 Javascript
完美实现仿QQ空间评论回复特效
May 06 Javascript
AngularJS实现网站换肤实例
Feb 19 Javascript
vue js秒转天数小时分钟秒的实例代码
Aug 08 Javascript
对Vue table 动态表格td可编辑的方法详解
Aug 28 Javascript
javascript实现文本框标签验证的实例代码
Oct 14 Javascript
vue拖拽组件 vuedraggable API options实现盒子之间相互拖拽排序
Jul 08 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缓存技术的多种方法小结
2012/08/14 PHP
php源码分析之DZX1.5字符串截断函数cutstr用法
2015/06/17 PHP
ThinkPHP表单令牌错误的相关解决方法分析
2016/05/20 PHP
php中引用符号(&)的使用详细介绍
2016/12/06 PHP
Nigma vs Liquid BO3 第一场2.13
2021/03/10 DOTA
通过百度地图获取公交线路的站点坐标的js代码
2012/05/11 Javascript
jQuery遮罩层实例讲解
2017/05/11 jQuery
jquery+ajax实现省市区三级联动 (封装和不封装两种方式)
2017/05/15 jQuery
vue 实现 tomato timer(蕃茄钟)实例讲解
2017/07/24 Javascript
详解tween.js的使用教程
2017/09/14 Javascript
JavaScript实现正则去除a标签并保留内容的方法【测试可用】
2018/07/18 Javascript
35个最好用的Vue开源库(史上最全)
2019/01/03 Javascript
vue实现后台管理权限系统及顶栏三级菜单显示功能
2019/06/19 Javascript
基于layui的下拉列表的数据回显方法
2019/09/24 Javascript
vue在路由中验证token是否存在的简单实现
2019/11/11 Javascript
JavaScript实现简单随机点名器
2019/11/21 Javascript
[01:00:25]NB vs Secret 2018国际邀请赛小组赛BO1 B组加赛 8.19
2018/08/21 DOTA
使用python实现ANN
2017/12/20 Python
python如何实现int函数的方法示例
2018/02/19 Python
django用户注册、登录、注销和用户扩展的示例
2018/03/19 Python
利用Python代码实现数据可视化的5种方法详解
2018/03/25 Python
对numpy和pandas中数组的合并和拆分详解
2018/04/11 Python
几个适合python初学者的简单小程序,看完受益匪浅!(推荐)
2019/04/16 Python
pyqt5实现绘制ui,列表窗口,滚动窗口显示图片的方法
2019/06/20 Python
Python异常处理例题整理
2019/07/07 Python
python实现PID算法及测试的例子
2019/08/08 Python
Python实现多线程/多进程的TCP服务器
2019/09/03 Python
Python通过fnmatch模块实现文件名匹配
2020/09/30 Python
CheapTickets香港机票预订网站:CheapTickets.hk
2019/06/26 全球购物
最热门的自我评价
2013/12/30 职场文书
女方婚礼新郎答谢词
2014/01/11 职场文书
旷课检讨书1000字
2014/02/14 职场文书
给孩子的新年寄语
2014/04/08 职场文书
农村门前三包责任书
2014/07/25 职场文书
个人委托书范本
2014/09/13 职场文书
整改落实自查报告
2014/11/05 职场文书