你必须知道的JavaScript 中字符串连接的性能的一些问题


Posted in Javascript onMay 07, 2013

而JavaScript的核心是ECMAScript 。与其他语言类似,ECMAScript 的字符串是不可变的,即它们的值不能改变。

请考虑下面的代码:

var str = "hello ";
str += "world";实际上,这段代码在幕后执行的步骤如下:

1.创建存储 "hello " 的字符串。
2.创建存储 "world" 的字符串。
3.创建存储连接结果的字符串。
4.把 str 的当前内容复制到结果中。
5.把 "world" 复制到结果中。
6.更新 str,使它指向结果。

每次完成字符串连接都会执行步骤 2 到 6,使得这种操作非常消耗资源。如果重复这一过程几百次,甚至几千次,就会造成性能问题。解决方法是用 Array 对象存储字符串,然后用 join() 方法(参数是空字符串)创建最后的字符串。想象用下面的代码代替前面的代码:

var arr = new Array();
arr[0] = "hello ";
arr[1] = "world";
var str = arr.join("");

这样,无论数组中引入多少字符串都不成问题,因为只在调用 join() 方法时才会发生连接操作。此时,执行的步骤如下:

1.创建存储结果的字符串
2.把每个字符串复制到结果中的合适位置
虽然这种解决方案很好,但还有更好的方法。问题是,这段代码不能确切反映出它的意图。要使它更容易理解,可以用 StringBuffer 类打包该功能:

function StringBuffer () {
  this._strings_ = new Array();
}
StringBuffer.prototype.append = function(str) {
  this._strings_.push(str);
};
StringBuffer.prototype.toString = function() {
  return this._strings_.join("");
};

这段代码首先要注意的是 strings 属性,本意是私有属性。它只有两个方法,即 append() 和 toString() 方法。append() 方法有一个参数,它把该参数附加到字符串数组中,toString() 方法调用数组的 join 方法,返回真正连接成的字符串。要用 StringBuffer 对象连接一组字符串,可以用下面的代码:
var buffer = new StringBuffer ();
buffer.append("hello ");
buffer.append("world");
var result = buffer.toString();

基于上面的实现我们来进行一下运行时间对比,即以“+”逐个进行字符串连接和我们封装的工具。可用下面的代码测试 StringBuffer 对象和传统的字符串连接方法的性能,在chrome控制台输入一下代码并运行:
var d1 = new Date();
var str = "";
for (var i=0; i < 10000; i++) {
    str += "text";
}
var d2 = new Date();
console.log("Concatenation with plus: "
 + (d2.getTime() - d1.getTime()) + " milliseconds");
var buffer = new StringBuffer();
d1 = new Date();
for (var i=0; i < 10000; i++) {
    buffer.append("text");
}
var result = buffer.toString();
d2 = new Date();
console.log("Concatenation with StringBuffer: "
 + (d2.getTime() - d1.getTime()) + " milliseconds");

这段代码对字符串连接进行两个测试,第一个使用加号,第二个使用 StringBuffer 类。每个操作都连接 10000 个字符串。日期值 d1 和 d2 用于判断完成操作需要的时间。请注意,创建 Date 对象时,如果没有参数,赋予对象的是当前的日期和时间。要计算连接操作历经多少时间,把日期的毫秒表示(用 getTime() 方法的返回值)相减即可。这是衡量 JavaScript 性能的常见方法。该测试的结果可以帮助您比较使用 StringBuffer 类与使用加号的效率差异。

上例运行结果如下:

你必须知道的JavaScript 中字符串连接的性能的一些问题

那么有人也许会说JavaScript的String对象中不是也封装一个concat()方法么,我们在下面也来用concat()方法来做同样的事情,在consoel输入以下代码:

var d1 = new Date();
var str = "";
for (var i=0; i < 10000; i++) {
    str.concat("text");
}
var d2 = new Date();
console.log("Concatenation with plus: "
 + (d2.getTime() - d1.getTime()) + " milliseconds");

我们可以看到做10000次字符窜连接它的耗时是:

你必须知道的JavaScript 中字符串连接的性能的一些问题

由此可以得出结论,当涉及到一定数量的字符串连接时,我们在Javascript中封装一个类似Java中的StringBuffer对象(函数)来进行操作会在性能上得到提升。

Javascript 相关文章推荐
js 获取子节点函数 (兼容FF与IE)
Apr 18 Javascript
JavaScript操纵窗口的方法小结
Jun 28 Javascript
两种方法实现在HTML页面加载完毕后运行某个js
Jun 16 Javascript
javascript中Math.random()使用详解
Apr 15 Javascript
基于jQuery实现美观且实用的倒计时实例代码
Dec 30 Javascript
JS代码实现table数据分页效果
May 26 Javascript
AngularJS表格添加序号的方法
Mar 03 Javascript
jQuery中hover方法搭配css的hover选择器,实现选中元素突出显示方法
May 08 jQuery
使用JQuery实现图片轮播效果的实例(推荐)
Oct 24 jQuery
Angular脚手架开发的实现步骤
Apr 09 Javascript
vue实现带过渡效果的下拉菜单功能
Feb 19 Javascript
详解js创建对象的几种方式和对象方法
Mar 01 Javascript
基于JavaScript实现继承机制之构造函数方法对象冒充的使用详解
May 07 #Javascript
基于JavaScript实现继承机制之调用call()与apply()的方法详解
May 07 #Javascript
JS中的substring和substr函数的区别说明
May 07 #Javascript
js图片自动切换效果处理代码
May 07 #Javascript
JavaScript通过RegExp实现客户端验证处理程序
May 07 #Javascript
JS注册/移除事件处理程序(ExtJS应用程序设计实战)
May 07 #Javascript
使用Math.floor与Math.random取随机整数的方法详解
May 07 #Javascript
You might like
PHP中UNIX时间戳和日期间的转换与计算实例
2014/11/19 PHP
完美解决thinkphp验证码出错无法显示的方法
2014/12/09 PHP
Yii框架弹出框功能示例
2017/01/07 PHP
PHP数据分析引擎计算余弦相似度算法示例
2017/08/08 PHP
JAVASCRIPT实现的WEB页面跳转以及页面间传值方法
2010/05/13 Javascript
javascript模拟select,jselect的方法实现
2012/11/08 Javascript
jquery根据name属性查找的小例子
2013/11/21 Javascript
node+express+jade制作简单网站指南
2014/11/26 Javascript
AngularJS + Node.js + MongoDB开发的基于高德地图位置的通讯录
2015/01/02 Javascript
JS+CSS实现感应鼠标渐变显示DIV层的方法
2015/02/20 Javascript
JS简单实现仿百度控制台输出信息效果
2016/09/04 Javascript
AngularJs 常用的过滤器
2017/05/15 Javascript
基于react框架使用的一些细节要点的思考
2017/05/31 Javascript
深入理解Vue 组件之间传值
2018/08/16 Javascript
如何将HTML字符转换为DOM节点并动态添加到文档中详解
2018/08/19 Javascript
分享5个顶级的JavaScript Ajax组件库
2018/09/16 Javascript
详解Angular模板引用变量及其作用域
2018/11/23 Javascript
Node.js JSON模块用法实例分析
2019/01/04 Javascript
在layui.use 中自定义 function 的正确方法
2019/09/16 Javascript
node.js使用 http-proxy 创建代理服务器操作示例
2020/02/10 Javascript
Python爬取网易云音乐热门评论
2017/03/31 Python
JavaScript实现一维数组转化为二维数组
2018/04/17 Python
浅谈Django的缓存机制
2018/08/23 Python
python numpy元素的区间查找方法
2018/11/14 Python
在Django的View中使用asyncio的方法
2019/07/12 Python
解决Python命令行下退格,删除,方向键乱码(亲测有效)
2020/01/16 Python
Django 自定义404 500等错误页面的实现
2020/03/08 Python
python中entry用法讲解
2020/12/04 Python
英国建筑用品在线:Building Supplies Online(BSO)
2018/04/30 全球购物
演讲稿祖国在我心中
2014/05/04 职场文书
安全生产目标管理责任书
2014/07/25 职场文书
全国法制宣传日活动总结2014
2014/11/01 职场文书
2015年学生会部门工作总结
2015/04/21 职场文书
会议室管理制度范本
2015/08/06 职场文书
opencv 分类白天与夜景视频的方法
2021/06/05 Python
分享五个Node.js开发的优秀实践 
2022/04/07 NodeJs