JS將字符串重復(fù)N次的repeat方法的8個(gè)版本
/*
*@desc: 將一個(gè)字符串重復(fù)自身N次
*/
//版本1:利用空數(shù)組的join方法
function repeat(target, n) {
return (new Array(n + 1)).join(target);
}
//版本2:之所以要?jiǎng)?chuàng)建一個(gè)帶length屬性的對(duì)象 是因?yàn)橐{(diào)用數(shù)據(jù)的原型方法晚缩,需要指定call的第一個(gè)參數(shù)為類數(shù)組對(duì)象
//類數(shù)組對(duì)象的必要條件是其length屬性的值為非負(fù)數(shù)
function repeat(target, n) {
return Array.prototype.join.call({
length: n + 1
}, target);
}
//版本3:利用閉包將類數(shù)組對(duì)象與數(shù)組原型的join方法緩存起來(lái)
var repeat = (function () {
var join = Array.prototype.join, obj = {};
return function (target, n) {
obj.length = n + 1;
return join.call(obj, target);
}
})();
//版本4:使用二分法
function repeat(target, n) {
var s = target, total = [];
while (n > 0) {
if (n % 2 == 1) {
total[total.length] = s;//如果是奇數(shù)
}
if (n == 1) {
break;
}
s += s;
n = n >> 1;//相當(dāng)于將n除以2取其商荞彼,或者說(shuō)是開(kāi)2次方
}
return total.join('');
}
//版本5:版本4的改良版本
function repeat(target, n) {
var s = target, total = "";
while (n > 0) {
if (n % 2 == 1) {
total += s;
}
if (n == 1) {
break;
}
s += s;
n = n >> 1;//相當(dāng)于將n除以2取其商卿泽,或者說(shuō)是開(kāi)2次方
}
return total;
}
//版本6:版本4的變樣版本 免去創(chuàng)建數(shù)組與使用join方法 但在循環(huán)中創(chuàng)建字符串比要求的還長(zhǎng) 所以...
function repeat(target, n) {
var s = target, c = s.length * n;
do {
s += s;
} while (n = n >> 1);
s = s.substring(0, c);
return s;
}
//版本7:版本5的優(yōu)化版本
function repeat(target, n) {
if (n == 1) {
return target;
}
var s = repeat(target, Math.floor(n / 2));
s += s;
if (n % 2) {
s += target;
}
return s;
}
//版本8:反例
function repeat(target, n) {
return (n <= 0) ? "" : target.concat(repeat(target, --n));
}
代碼轉(zhuǎn)自靜逸的博客
分別運(yùn)行8個(gè)方法莺债,執(zhí)行repeat(1,200000000),每個(gè)方法運(yùn)行50次签夭,得出的結(jié)果(平均值)
- 版本1 88ms
- 版本2 瀏覽器崩潰
- 版本3 瀏覽器崩潰
- 版本4 <1ms
- 版本5 <1ms
- 版本6 報(bào)錯(cuò)(詳見(jiàn)代碼注釋)
- 版本7 <1ms
- 版本8 瀏覽器崩潰