JavaScript 字符串乘法技巧:利用 Array.join 高效重复字符串

作者:异步漫步

时间:2026-10-23

浏览:148

本文介绍在JavaScript中实现字符串乘法(重复)的两种技巧。首先解析利用Array.prototype.join和length属性避免创建完整数组的高效写法,随后对比递归优化算法,探讨不同场景下的执行效率与代码优雅性平衡。

文章目录

JavaScript 字符串乘法技巧:利用 Array.join 高效重复字符串

原文地址:http://www.davidflanagan.com/2009/08/string-multipli.html 原作者:David Flanagan 在Ruby语言中,“*”操作符支持以字符串为左参数、数字为右参数来实现字符串重复,例如 "Ruby" * 2 的结果为 "RubyRuby"。这一特性虽应用场景有限(如生成由连字符等ASCII字符构成的表格),但写法简洁,优于手动编写循环连接n次字符串的低效方式。 作者发现JavaScript中也有类似的巧妙实现方法:

代码如下:

 
String.prototype.times = function(n) {
return Array.prototype.join.call({length:n+1}, this);
}; 
"js".times(5) // => "jsjsjsjsjs"


该方法的核心在于利用全为“undefined”元素的数组调用Array.join()的行为,但关键在于它并未真正创建包含 n+1 个“undefined”元素的完整数组。而是通过一个仅包含 length 属性的匿名对象,借助 Array 原型上的 join() 函数实现。由于普通 Object 无法直接调用 join(),因此必须通过原型链的 call() 方法间接执行。以下是一个效果相同但更直观的版本:



代码如下:

 
String.prototype.times = function(n) { return (new Array(n+1)).join(this);};

当调用带有一个参数的 Array 构造函数时,实际上只是设置了数组的 length 属性,而并未真正创建数组元素。



该方案仅在 Firefox 浏览器下进行了测试,作者推测其性能优于普通循环,但未进行严格的基准测试验证。



作者简介


David Flanagan 是一位专注于技术写作的计算机程序员,主要致力于Java相关图书的编写。他拥有麻省理工学院计算机科学及工程学位,居住在美国太平洋西北海岸(西雅图与温哥华之间)。其由O'Reilly出版的畅销书籍包括《Java in a Nutshell》、《Java Foundation Classes in a Nutshell》、《Java Enterprise in a Nutshell》、《JavaScript: The Definitive Guide》、《JavaScript Pocket Reference》以及《The Ruby Programming Language》等。



性能优化:递归算法与循环对比

我的评论


若从效率角度考量,对循环迭代稍作优化可能获得更高性能。例如以下递归调用版本,算法复杂度为 O(log2n)。在 Google Chrome 浏览器下的测试结果显示其执行速度比 David 的原方法更快,尽管不得不承认原方法在代码结构上更为优雅。


代码如下:

 
String.prototype.times = function(n) {
if ( n == 1 ) {
return this;
} 
var midRes = this.times(Math.floor(n/2));
midRes += midRes;
if ( n % 2 ) {
midRes += this;
} 
return midRes;
} 

后记


David 采纳了上述建议,并撰写了一段非递归版本的代码。详情请参考他的博客原文:http://www.davidflanagan.com/2009/08/good-algorithms.html


联系方式


邮箱:redraiment@gmail.com,欢迎来信交流。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章