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函数、方法、对象代码
Oct 29 Javascript
js数字输入框(包括最大值最小值限制和四舍五入)
Nov 24 Javascript
js读取本地excel文档数据的代码
Nov 11 Javascript
JS对文本框值的判断示例
Mar 10 Javascript
基于jQuery日历插件制作日历
Mar 11 Javascript
jquery select2的使用心得(推荐)
Dec 04 Javascript
Node.js的特点详解
Feb 03 Javascript
vue实现点击隐藏与显示实例分享
Feb 13 Javascript
VUE子组件向父组件传值详解(含传多值及添加额外参数场景)
Sep 01 Javascript
在vue中使用cookie记住用户上次选择的实例(本次例子中为下拉框)
Sep 11 Javascript
PHP 502bad gateway原因及解决方案
Nov 13 Javascript
原生JS实现拖拽效果
Dec 04 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
广播爱好者需要了解的天线知识
2021/03/01 无线电
解析php5配置使用pdo
2013/07/03 PHP
ThinkPHP CURD方法之order方法详解
2014/06/18 PHP
PHP处理Ajax请求与Ajax跨域问题
2017/02/13 PHP
PHP基于SMTP协议实现邮件发送实例代码
2017/04/27 PHP
PHP实现文件下载【实例分享】
2017/04/28 PHP
Yii输入正确验证码却验证失败的解决方法
2017/06/06 PHP
PHP获取MySQL执行sql语句的查询时间方法
2018/08/21 PHP
php实现的PDO异常处理操作分析
2018/12/27 PHP
再谈JavaScript线程
2015/07/10 Javascript
动态的9*9乘法表效果的实现代码
2016/05/16 Javascript
JavaScript编程中实现对象封装特性的实例讲解
2016/06/24 Javascript
ES6中Array.includes()函数的用法
2017/09/20 Javascript
基于JavaScript实现幸运抽奖页面
2020/07/05 Javascript
三分钟教你用Node做一个微信哄女友(基友)神器(面向小白)
2019/06/21 Javascript
JavaScript实现随机五位数验证码
2019/09/27 Javascript
js+css实现扇形导航效果
2020/08/18 Javascript
Python基于pygame实现的弹力球效果(附源码)
2015/11/11 Python
基于DataFrame筛选数据与loc的用法详解
2018/05/18 Python
基于Django URL传参 FORM表单传数据 get post的用法实例
2018/05/28 Python
学习python分支结构
2019/05/17 Python
python实现图片压缩代码实例
2019/08/12 Python
python自动化工具之pywinauto实例详解
2019/08/26 Python
Django REST框架创建一个简单的Api实例讲解
2019/11/05 Python
python的sys.path模块路径添加方式
2020/03/09 Python
Python爬虫JSON及JSONPath运行原理详解
2020/06/04 Python
keras读取h5文件load_weights、load代码操作
2020/06/12 Python
html5 的a标签 Href 拨电话的写法
2013/11/04 HTML / CSS
台湾演唱会订票网站:StubHub台湾
2019/06/11 全球购物
优秀学生自我鉴定范例
2013/12/18 职场文书
成功的餐厅经营创业计划书
2014/01/15 职场文书
安全标准化汇报材料
2014/02/03 职场文书
合作意向书范本
2014/03/31 职场文书
党风廉政建设责任书
2014/04/14 职场文书
教师自查自纠材料
2014/10/14 职场文书
vue实力踩坑之push当前页无效
2022/04/10 Vue.js