你必须知道的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 相关文章推荐
[原创]来自ImageSee官方 JavaScript图片浏览器
Jan 16 Javascript
js中的window.open返回object的错误的解决方法
Aug 15 Javascript
js页面滚动时层智能浮动定位实现(jQuery/MooTools)
Aug 23 Javascript
简单的Jquery全选功能
Nov 07 Javascript
jquery简单实现滚动条下拉DIV固定在头部不动
Nov 25 Javascript
jquery 快速回到页首的方法
Dec 05 Javascript
JS实现用户注册时获取短信验证码和倒计时功能
Oct 27 Javascript
js实现的在线调色板功能完整实例
Dec 21 Javascript
js实现功能比较全面的全选和多选
Mar 02 Javascript
SelectPage v2.4 发布新增纯下拉列表和关闭分页功能
Sep 07 Javascript
解决Vue.js父组件$on无法监听子组件$emit触发事件的问题
Sep 12 Javascript
JS实现拖拽元素时与另一元素碰撞检测
Aug 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简单选择排序算法实例
2015/01/26 PHP
支持中文的PHP按字符串长度分割成数组代码
2015/05/17 PHP
php的mail函数发送UTF-8编码中文邮件时标题乱码的解决办法
2015/10/20 PHP
php生成二维码图片方法汇总
2016/12/17 PHP
PHP工厂模式、单例模式与注册树模式实例详解
2019/06/03 PHP
JavaScript中SQL语句的应用实现
2010/05/04 Javascript
JavaScript高级程序设计 阅读笔记(十三) js定义类或对象
2012/08/14 Javascript
js 固定悬浮效果实现思路代码
2013/08/02 Javascript
js实现checkbox全选和反选示例
2014/05/01 Javascript
JavaScript实现给按钮加上双重动作的方法
2015/08/14 Javascript
详解Wondows下Node.js使用MongoDB的环境配置
2016/03/01 Javascript
JS面向对象编程详解
2016/03/06 Javascript
javascript输出AscII码扩展集中的字符方法
2016/12/26 Javascript
js实现数组去重方法及效率?Ρ? target=
2017/02/14 Javascript
js仿新浪微博消息发布功能
2017/02/17 Javascript
jQuery树控件zTree使用方法详解(一)
2017/02/28 Javascript
使用typescript开发angular模块并发布npm包
2018/04/19 Javascript
关于AngularJS中ng-repeat不更新视图的解决方法
2018/09/30 Javascript
JS实现深度优先搜索求解两点间最短路径
2019/01/17 Javascript
浅析vue中的MVVM实现原理
2019/03/04 Javascript
Vue 路由间跳转和新开窗口的方式(query、params)
2019/12/25 Javascript
[55:45]DOTA2上海特级锦标赛D组败者赛 Liquid VS COL第一局
2016/02/28 DOTA
Python素数检测的方法
2015/05/11 Python
Python3 max()函数基础用法
2019/02/19 Python
django echarts饼图数据动态加载的实例
2019/08/12 Python
django配置app中的静态文件步骤
2020/03/27 Python
Django+Uwsgi+Nginx如何实现生产环境部署
2020/07/31 Python
python反爬虫方法的优缺点分析
2020/11/25 Python
美国钻石商店:Zales
2016/11/20 全球购物
全球最大的网上自行车商店:Chain Reaction Cycles
2016/12/02 全球购物
社区七一党员活动方案
2014/01/25 职场文书
关于迟到的检讨书
2014/01/26 职场文书
2014信息公开实施方案
2014/02/22 职场文书
小学二年级评语
2014/04/21 职场文书
2014年平安夜寄语
2014/12/08 职场文书
Python数据分析之pandas函数详解
2021/04/21 Python