你必须知道的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 相关文章推荐
jQuery 页面载入进度条实现代码
Feb 08 Javascript
JS链式调用的实现方法
Mar 07 Javascript
js给onclick赋值传参数的两种方法
Nov 25 Javascript
JS 在指定数组中随机取出N个不重复的数据
Jun 10 Javascript
3个可以改善用户体验的AngularJS指令介绍
Jun 18 Javascript
JavaScript实现打字效果的方法
Jul 10 Javascript
jquery 实现输入邮箱时自动补全下拉提示功能
Oct 04 Javascript
jquery 判断selection range 是否在容器中的简单实例
Aug 02 Javascript
JavaScript数据结构与算法之队列原理与用法实例详解
Nov 22 Javascript
浅谈jquery fullpage 插件增加头部和版权的方法
Mar 20 jQuery
解决element UI 自定义传参的问题
Aug 22 Javascript
JavaScript惰性载入函数实例分析
Mar 27 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 mcrypt可逆加密算法分析
2011/07/19 PHP
PHP中使用json数据格式定义字面量对象的方法
2014/08/20 PHP
php 魔术方法详解
2014/11/11 PHP
PHP生成不重复随机数的方法汇总
2014/11/19 PHP
php数组转成json格式的方法
2015/03/09 PHP
Ubuntu 16.04下安装PHP 7过程详解
2017/03/28 PHP
PHP实现的简单异常处理类示例
2017/05/04 PHP
PHP排序算法之堆排序(Heap Sort)实例详解
2018/04/21 PHP
PHP实现微信小程序人脸识别刷脸登录功能
2018/05/24 PHP
很可爱的输入框
2008/08/03 Javascript
Javascript 实现TreeView CheckBox全选效果
2010/01/11 Javascript
javascript 日期时间 转换的方法
2013/02/21 Javascript
基于JavaScript实现购物网站商品放大镜效果
2016/09/06 Javascript
Vue.js实现在下拉列表区域外点击即可关闭下拉列表的功能(自定义下拉列表)
2017/05/30 Javascript
jQuery列表检索功能实现代码
2017/07/17 jQuery
微信小程序checkbox组件使用详解
2018/01/31 Javascript
vue-cli webpack模板项目搭建及打包时路径问题的解决方法
2018/02/26 Javascript
jQuery实现的点击显示隐藏下拉菜单功能完整示例
2019/05/17 jQuery
VUE 组件转换为微信小程序组件的方法
2019/11/06 Javascript
Python中单、双下划线的区别总结
2017/12/01 Python
python如何将图片转换为字符图片
2020/08/19 Python
python: 自动安装缺失库文件的方法
2018/10/22 Python
ORM Django 终端打印 SQL 语句实现解析
2019/08/09 Python
python读取excel数据绘制简单曲线图的完整步骤记录
2020/10/30 Python
一篇文章教你用python画动态爱心表白
2020/11/22 Python
canvas三角函数模拟水波效果的示例代码
2018/07/03 HTML / CSS
波兰最大的度假胜地和城市公寓租赁运营商:Sun & Snow
2018/10/18 全球购物
文字自荐书范文
2014/02/10 职场文书
应届毕业生如何写求职信
2014/02/16 职场文书
培训专员岗位职责
2014/02/26 职场文书
监察建议书格式
2014/05/19 职场文书
十佳青年事迹材料
2014/08/21 职场文书
房屋出售授权委托书
2014/10/12 职场文书
影视后期实训报告
2014/11/05 职场文书
挂职锻炼个人总结
2015/03/05 职场文书
QT与javascript交互数据的实现
2021/05/26 Javascript