用JavaScript重复一个字符串多次

854
在Perl中,我可以使用语法重复多次一个字符:

在Perl中,我可以使用以下语法重复多次一个字符:

$a = "a" x 10; // results in "aaaaaaaaaa"

有没有在Javascript中实现这个的简单方法?我当然可以使用函数,但我想知道是否有任何内置的方法或其他巧妙的技术。

24个回答

1634

现在几乎所有地方都已经实现了repeat字符串方法。(它在Internet Explorer中不可用。)所以,除非你需要支持旧版浏览器,你可以简单地编写:

"a".repeat(10)

repeat之前,我们使用了这个技巧:

Array(11).join("a") // create string with 10 a's: "aaaaaaaaaa"

(Note that an array of length 11 gets you only 10 "a"s, since Array.join puts the argument between the array elements.)
Simon还指出,根据这个基准测试,在Safari和Chrome中多次重复一个字符似乎更快(但不是Firefox),只需使用for循环简单地附加即可(虽然不太简洁)。

6
此外,您可以使用变量而不是固定的长度 - Array(20-len),来填充一个字符串,使其达到20个字符。 - John C
8
循环方法可能更快,但更冗长。另外,我对第一条评论的所有点赞感到困惑,因为通常只有在数组长度可变时才会有用,例如 Array(rawValue.length + 1).join("*") - Dexygen
当您尝试使用10的12次方(Math.pow(10, 12))时,它无法正常工作。 Array(Math.pow(10, 12)).join("a") - Neel Rathod
3
@Neel 这是因为JS引擎对字符串长度有限制。在Chrome和Firefox中,限制接近于2^30(约十亿)。10^12是一万亿。 - Jason Orendorff
1
我想知道这个字符串是什么,让成千上万的程序员如此热衷于重复。难道你们没有听说过DRY原则吗? - Jason Orendorff

322
在新的ES6标准中,你可以使用本地方式使用repeat函数来实现这一点。目前ES6仍处于实验阶段,但此功能在Edge、FF、Chrome和Safari浏览器中已经可用
"abc".repeat(3) // "abcabcabc"

当然,如果没有可用的重复函数,您可以使用老式的好方法Array(n + 1).join("abc")


57

如果你经常需要重复自己,那么很方便:

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

alert(  'Are we there yet?\nNo.\n'.repeat(10)  )


57
在编程中修改内置对象的原型是一种糟糕的编码实践。 - tuomassalo
4
请查看http://programmers.stackexchange.com/questions/104320/why-is-extending-the-dom-built-in-object-prototypes-a-bad-idea以获取更多讨论。我建议添加一个(正确作用域的)静态帮助函数,签名为`repeat(str, n)`。 - tuomassalo
6
我会尽力完成这项任务。建议更改为:移除 n = n || 1 部分(或者检查 n 是否未定义),这样你也可以重复 0 次。 - chodorowicz
5
请查看 Mozilla 官方 ES6 的 polyfill: https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/repeat - Eirik Birkeland
4
@ChrisV,String.repeat 方法是在 ES6 中加入的,在那之前它并不存在。ES6 是在2015年6月才最终确定的。所以我认为我在2012年写下这句话时是正确的。 :) - tuomassalo
显示剩余3条评论

19
Array(10).fill('a').join('')

虽然最被投票的答案更加紧凑,但是采用这种方法你不需要再添加额外的数组项。


1
很遗憾,IE不支持fill方法,如果您的浏览器不兼容IE,可以使用repeat方法。 - Michiel
1
如果你只是用join("a")就能实现相同的功能,为什么还要使用额外的方法fill()呢? - vsync
3
如果您需要一个分隔符,这个答案会很有用。 - Archimedes Trajano

15

另一种选择是:

for(var word = ''; word.length < 10; word += 'a'){}

如果你需要重复多个字符,请将条件乘以相应的倍数:

for(var word = ''; word.length < 10 * 3; word += 'foo'){}

注意:word = Array(11).join('a')中超出一个的情况不同,您无需超过当前数量。


12

最高性能的方法是使用String.repeat()

简短版如下。

  String.prototype.repeat = function(count) {
    if (count < 1) return '';
    var result = '', pattern = this.valueOf();
    while (count > 1) {
      if (count & 1) result += pattern;
      count >>>= 1, pattern += pattern;
    }
    return result + pattern;
  };
  var a = "a";
  console.debug(a.repeat(10));

来自Mozilla的Polyfill:

if (!String.prototype.repeat) {
  String.prototype.repeat = function(count) {
    'use strict';
    if (this == null) {
      throw new TypeError('can\'t convert ' + this + ' to object');
    }
    var str = '' + this;
    count = +count;
    if (count != count) {
      count = 0;
    }
    if (count < 0) {
      throw new RangeError('repeat count must be non-negative');
    }
    if (count == Infinity) {
      throw new RangeError('repeat count must be less than infinity');
    }
    count = Math.floor(count);
    if (str.length == 0 || count == 0) {
      return '';
    }
    // Ensuring count is a 31-bit integer allows us to heavily optimize the
    // main part. But anyway, most current (August 2014) browsers can't handle
    // strings 1 << 28 chars or longer, so:
    if (str.length * count >= 1 << 28) {
      throw new RangeError('repeat count must not overflow maximum string size');
    }
    var rpt = '';
    for (;;) {
      if ((count & 1) == 1) {
        rpt += str;
      }
      count >>>= 1;
      if (count == 0) {
        break;
      }
      str += str;
    }
    // Could we try:
    // return Array(count + 1).join(this);
    return rpt;
  }
}

这是一个不错的选择,但新的本地“repeat”更快,而且不需要实现,无论如何还是谢谢! - Goty Metal
1
你能详细解释一下 count >>>= 1, pattern += pattern; 的含义吗?这是什么类型的语句? - Tsahi Asher
这是为了本地重复而设计的polyfill吗?只需在开头添加if (!String.prototype.repeat) {,并在结尾处添加}即可。 - trlkly
">>>=" 是无符号右移位赋值运算符(例如 count = count >>> 1),请参见:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Assignment_Operators#Unsigned_right_shift_assignment。 - user1441004

11

10

适用于所有浏览器

下面的函数将比接受答案中提供的选项执行得更快:

var repeat = function(str, count) {
    var array = [];
    for(var i = 0; i < count;)
        array[i++] = str;
    return array.join('');
}

你可以像这样使用它:

var repeatedString = repeat("a", 10);

要比较此功能与已接受答案中提出的选项的性能,请参见this Fiddlethis Fiddle以获取基准测试结果。

仅适用于现代浏览器

在现代浏览器中,您现在可以使用String.prototype.repeat方法来执行此操作:

var repeatedString = "a".repeat(10);

MDN上阅读更多关于这种方法的信息。

这个选项速度更快,但不幸的是,在任何版本的Internet Explorer中都不起作用。表格中的数字指定完全支持该方法的第一个浏览器版本:

输入图像描述


8

String.repeat() 目前已被96.39%的浏览器支持。

function pad(text, maxLength){ 
  return text + "0".repeat(maxLength - text.length);
}
console.log(pad('text', 7)); //text000

7
在ES2015/ES6中,你可以使用"*".repeat(n)来实现。将其添加到你的项目中,你就可以开始了。
  String.prototype.repeat = String.prototype.repeat || 
    function(n) {
      if (n < 0) throw new RangeError("invalid count value");
      if (n == 0) return "";
      return new Array(n + 1).join(this.toString()) 
    };

SCRIPT5029:使用此方法时,数组长度必须是有限正整数。 - andrepaulo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接