当前位置: 首页 > news >正文

如何更高效的拼接字符串?

最常用的连接字符串的方法应该是下面几种:

// 1.=操作符
str = 'a' + 'b' + 'c';
// 2. +=操作符
str = 'a';
str += 'b';
str += 'c';
// 3. Array.join()
str = ['a', 'b', 'c'].join('');
// 4. String.concat()
str = 'a';
str = str.concat('b', 'c');
复制代码

那么来看一下这几种有什么区别,或者会造成什么影响。


= 和 +=操作符

运行str += 'one' + 'two'会经历以下4个过程:

  1. 在内存中创建一个临时字符串;
  2. 连接后的字符串onetwo被赋值给该临时字符串;
  3. 临时字符串与str当前的值连接;
  4. 结果赋值给str

拼接这个短短的字符串就会经历以上4个步骤,那么可以进行优化吗?请看下面的代码:

// 1
str += 'one';
str += 'two';
// 2
str = str + 'one' + 'two';
复制代码

以上两种方式虽然能达到同样的效果,但是却可以避免产生临时字符串(也就是4个步骤中的1&2步骤);在大多数浏览器中这样做会提速10%~40%(IE7以上,IE8效果不明显,实现机制与此不同)。

但是如果将上面的代码2换成:str = 'one' + str + 'two',则优化将失效。这与浏览器合并字符串时分配内存的方法有关:

除IE外,其他浏览器会尝试为表达式左侧的字符串分配更多的内存,然后简单地将第二个字符串拷贝至它的末尾。如果在一个循环中,基础字符串位于最左端的位置,就可以避免重复拷贝一个逐渐变大的基础字符串。

基本字符串可以理解为连接时排在前面的字符串。也就是说:str + 'one'意味着拷贝one并附加在str之后,而'one' + str则意味着要拷贝str并附加在'one'之后,如果str很大,拷贝过程的性能损耗(内存占用)就会很高。

说回IE8的实现机制:

在IE8的实现中,连接字符串只是记录现有的字符串的引用来构造新的字符串。在最后时刻(当你真正要使用连接后的字符串时),字符串的各个部分才会逐个拷贝到一个新的“真正的”字符串中,然后用它取代先前的字符串引用,所以并非每次使用字符串时都发生合并操作。

而IE7的实现机制更糟糕:

每连接一对字符串都要把它复制到一块新分配的内存中。

Array.join() 和 String.prototype.concat()

大多数浏览器中,数组项合并比其他字符串连接方法更慢

Array.join()当把所有的数组的元素连接在一起时,浏览器会分配足够的内存来存放整个字符串,而且不会多次拷贝最终字符串中相同的部分。

字符串的原生方法concat()能接收任意数量的参数,并将每一个参数附加到所调用的字符串上。但是多数情况下,使用concat()比使用简单的++=稍慢,尤其在IE,Opera和Chrome中慢得更明显。


在《高性能JavaScript》看到了就记录一下,方便以后查看。

转载于:https://juejin.im/post/5c0bd697f265da613d7be3f5

相关文章:

  • C# 多线程六之Task(任务)三之任务工厂
  • 整数规划---整数规划问题的提出
  • React+TypeScript入门
  • MySql行转列、列转行
  • @ModelAttribute注解使用
  • docker容器内的网络抓包
  • 【linux】linux重启tomcat + 实时查看tomcat启动日志
  • JavaScript基础——基本概念
  • 一步一步教你用 Vue.js + Vuex 制作专门收藏微信公众号的 app
  • 【MySQL经典案例分析】 Waiting for table metadata lock
  • Innodb之全局共享内存
  • sql 开窗函数
  • 我的友情链接
  • 实现菜单下拉伸展折叠效果demo
  • Android中的树状(tree)列表
  • (十五)java多线程之并发集合ArrayBlockingQueue
  • [译] 理解数组在 PHP 内部的实现(给PHP开发者的PHP源码-第四部分)
  • 2017前端实习生面试总结
  • Android Studio:GIT提交项目到远程仓库
  • Angular 响应式表单之下拉框
  • PyCharm搭建GO开发环境(GO语言学习第1课)
  • SpringCloud(第 039 篇)链接Mysql数据库,通过JpaRepository编写数据库访问
  • 给初学者:JavaScript 中数组操作注意点
  • 老板让我十分钟上手nx-admin
  • 前端面试题总结
  • 听说你叫Java(二)–Servlet请求
  • 一个JAVA程序员成长之路分享
  • 没有任何编程基础可以直接学习python语言吗?学会后能够做什么? ...
  • ​linux启动进程的方式
  • ​一帧图像的Android之旅 :应用的首个绘制请求
  • (06)金属布线——为半导体注入生命的连接
  • (1)Nginx简介和安装教程
  • (aiohttp-asyncio-FFmpeg-Docker-SRS)实现异步摄像头转码服务器
  • (编程语言界的丐帮 C#).NET MD5 HASH 哈希 加密 与JAVA 互通
  • (二)Pytorch快速搭建神经网络模型实现气温预测回归(代码+详细注解)
  • (分布式缓存)Redis哨兵
  • (附源码)计算机毕业设计SSM教师教学质量评价系统
  • (附源码)计算机毕业设计SSM在线影视购票系统
  • (详细版)Vary: Scaling up the Vision Vocabulary for Large Vision-Language Models
  • (一)80c52学习之旅-起始篇
  • (原創) 如何讓IE7按第二次Ctrl + Tab時,回到原來的索引標籤? (Web) (IE) (OS) (Windows)...
  • (转)原始图像数据和PDF中的图像数据
  • (转载)利用webkit抓取动态网页和链接
  • .NET / MSBuild 扩展编译时什么时候用 BeforeTargets / AfterTargets 什么时候用 DependsOnTargets?
  • .NET 5.0正式发布,有什么功能特性(翻译)
  • .NET Core中Emit的使用
  • .net 流——流的类型体系简单介绍
  • .NET/C# 反射的的性能数据,以及高性能开发建议(反射获取 Attribute 和反射调用方法)
  • .net反编译工具
  • .NET开发不可不知、不可不用的辅助类(一)
  • /etc/sudoer文件配置简析
  • @Not - Empty-Null-Blank
  • @Transient注解
  • [ Linux 长征路第二篇] 基本指令head,tail,date,cal,find,grep,zip,tar,bc,unname
  • [Android]如何调试Native memory crash issue