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 相关文章推荐
jQuery实现长按按钮触发事件的方法
Feb 02 Javascript
谷歌showModalDialog()方法不兼容出现对话窗口的解决办法
Feb 15 Javascript
百度地图给map添加右键菜单(判断是否为marker)
Mar 04 Javascript
简单实现node.js图片上传
Dec 18 Javascript
基于jQuery实现顶部导航栏功能
Dec 27 Javascript
javaScript嗅探执行神器-sniffer.js
Feb 14 Javascript
学习使用Bootstrap栅格系统
May 11 Javascript
JS禁止浏览器右键查看元素或按F12审查元素自动关闭页面示例代码
Sep 07 Javascript
Angular实现点击按钮控制隐藏和显示功能示例
Dec 29 Javascript
js中自定义react数据验证组件实例详解
Oct 19 Javascript
Angular7.2.7路由使用初体验
Mar 01 Javascript
Vue $mount实战之实现消息弹窗组件
Apr 22 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
joomla内置的表单验证功能使用方法
2010/06/11 PHP
PHP错误处理函数
2016/04/03 PHP
File, FileReader 和 Ajax 文件上传实例分析(php)
2011/04/27 Javascript
Extjs中TabPane如何嵌套在其他网页中实现思路及代码
2013/01/27 Javascript
javascript 用函数语句和表达式定义函数的区别详解
2014/01/06 Javascript
JavaScript立即执行函数的三种不同写法
2014/09/05 Javascript
JQuery拖动表头边框线调整表格列宽效果代码
2014/09/10 Javascript
JQuery radio(单选按钮)操作方法汇总
2015/04/15 Javascript
javascript实现获取字符串hash值
2015/05/10 Javascript
jquery插件jquery.nicescroll实现图片无滚动条左右拖拽的方法
2015/08/10 Javascript
jQuery鼠标事件汇总
2015/08/30 Javascript
jQuery实现鼠标经过时出现隐藏层文字链接的方法
2015/10/12 Javascript
使用jQuery调用XML实现无刷新即时聊天
2016/08/07 Javascript
JS实现将链接生成二维码并转为图片的方法
2018/03/17 Javascript
微信小程序实现日历效果
2018/12/28 Javascript
微信小程序实现的canvas合成图片功能示例
2019/05/03 Javascript
Node.js安装详细步骤教程(Windows版)详解
2019/09/01 Javascript
vue中实现高德定位功能
2019/12/03 Javascript
VUE项目实现主题切换的多种方法
2020/11/26 Vue.js
在Python中过滤Windows文件名中的非法字符方法
2019/06/10 Python
Python学习笔记之lambda表达式用法详解
2019/08/08 Python
Python自动化导出zabbix数据并发邮件脚本
2019/08/16 Python
浅谈Pytorch torch.optim优化器个性化的使用
2020/02/20 Python
基于python实现音乐播放器代码实例
2020/07/01 Python
python实现简单的五子棋游戏
2020/09/01 Python
CSS3实现时间轴效果
2016/07/11 HTML / CSS
css3动画 小球滚动 js控制动画暂停
2019/11/29 HTML / CSS
教师旷工检讨书
2014/01/18 职场文书
课外小组活动总结
2014/08/27 职场文书
就业协议书怎么填
2014/09/15 职场文书
机关工会工作总结2015
2015/05/26 职场文书
太行山上观后感
2015/06/05 职场文书
超市店长竞聘书
2015/09/15 职场文书
小型企业的绩效考核制度模板
2019/11/21 职场文书
Java 多线程并发FutureTask
2022/06/28 Java/Android
MySQL表字段数量限制及行大小限制详情
2022/07/23 MySQL