JS将字符串重复N次的repeat方法的8个版本
/*
*@desc: 将一个字符串重复自身N次
*/
//版本1:利用空数组的join方法
function repeat(target, n) {
return (new Array(n + 1)).join(target);
}
//版本2:之所以要创建一个带length属性的对象 是因为要调用数据的原型方法,需要指定call的第一个参数为类数组对象
//类数组对象的必要条件是其length属性的值为非负数
function repeat(target, n) {
return Array.prototype.join.call({
length: n + 1
}, target);
}
//版本3:利用闭包将类数组对象与数组原型的join方法缓存起来
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;//如果是奇数
}
if (n == 1) {
break;
}
s += s;
n = n >> 1;//相当于将n除以2取其商,或者说是开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;//相当于将n除以2取其商,或者说是开2次方
}
return total;
}
//版本6:版本4的变样版本 免去创建数组与使用join方法 但在循环中创建字符串比要求的还长 所以...
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的优化版本
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));
}
代码转自静逸的博客
分别运行8个方法,执行repeat(1,200000000),每个方法运行50次,得出的结果(平均值)
- 版本1 88ms
- 版本2 浏览器崩溃
- 版本3 浏览器崩溃
- 版本4 <1ms
- 版本5 <1ms
- 版本6 报错(详见代码注释)
- 版本7 <1ms
- 版本8 浏览器崩溃
网友评论