JavaScript字符串反转

JavaScript中,字符串反转算是一个常见的前端面试题了。下面由简单到复杂总结了几种方式。

1、for循环

        说实话,这是最容易想到的方式了,因为不管是菜鸟还是高级前端,对for循环真的是烂熟于心,尽管高级的早已抛弃它。

function reverseString(str){
    var res = new Array(),
        len = str.length;

    for(var i = (len-1); i >= 0; i--){
        res.push(str.charAt(i));
    }
    return res.join("");
}
var str = "abcdefg";
console.log(reverseString(str)); // "gfedcba"

        定义一个数组res,然后对str倒着循环,利用charAt()访问字符串某个索引上对应的项,push到数组中,然后将数组res转化成字符串返回。此方法不会改变原来的字符串。要是不牵扯到数组该怎么做呢?

function reverseString(str) {
     var res = "",
         len = str.length - 1;

     for (var i = len; i >= 0; i--) {
          res += str.charAt(i);
     }
     return res;
}
var str = "abcdefg";
console.log(reverseString(str)); // "gfedcba"

上面代码中的charAt()方法也可用substr(i, 1),substring(i, i+1),slice(i, i+1)来代替,这三个方法是字符串中很常用的方法,而且差别细微,有必要研究一下QAQ。

2、map()或forEach()函数循环

    既然有循环的方法,那么自然就想到map()和forEach()了,不过IE8及以下低版本不支持这两个方法。既然它们是数组方法,那么要先将字符串转化成数组。下面以map()为例:

function reverseString(str){
    var res = new Array();
    str.split("").map(function(item, index, array){
        res.unshift(item);
    });
    return res.join("");
}
var str = "abcdefg";
console.log(reverseString(str)); // "gfedcba"

在map()循环中,利用unshift()方法在数组头部添加项,由此最先添加的在数组后面,就像队列一样。

3、利用数组的反转方法reverse()

function reverseString(str){
    str = str.split("");
    str.reverse();
    return str.join("");
}
var str = "abcdefg";
console.log(reverseString(str));

利用split()方法将字符串转化成数组,然后调用数组反转方法reverse(),代码比for循环简洁不少。此方法不会改变原来的字符串。上面代码看着咋有点别扭呢?split()结果赋值,调用reverse(),又在return语句中调用join(),知道了split()方法的返回值难道还需要一步一步赋值吗?看代码:

function reverseString(str){
    return str.split("").reverse().join("");
}

哇,这么神奇,是不是嗅到了一点函数式编程的味道了,更不可思议的还在后面!

4、利用reduce()和reduceRight()两个方法实现

function reverseString(str){
    return str.split("").reduce((prev, cur, index, array) => {return cur + prev});
}
var str = "abcdefg";
console.log(reverseString(str));  // "gfedcba"

又或者:

function reverseString(str){
    return str.split("").reduceRight((prev, cur, index, array) => {return prev + cur});
}
var str = "abcdefg";
console.log(reverseString(str)); // "gfedcba"

这两个方法是数组的归并方法(具体介绍请看http://blog.csdn.net/zrn1812083198/article/details/79487641),很少有人会想到用它们实现这个反转功能,而且是ES6写法,这个比循环更为高级,可读性也非常高。

       稍微成熟一点的前端开发工程师就会发现上面代码的一个诟病,是的,那就是都没有考虑到异常情况,这是很不可取的。不管是在面试中回答面试官的问题还是在实际项目中敲代码,逻辑考虑地是否周全非常重要,因为看上去非常美的代码,它的健壮性却很差,没办法百分百通过所有的情况。就像上面代码一样,假如向下面这样没有传递参数,结果是怎样的,你我都心知肚明。

reverseString();   // 这里相当于undefined
reverseString(null); // 这里是null, error, error中直接undefined变成null了

是的,惨不忍睹QAQ。


error, oh, my god。一切都白费了,看着如此美的代码,结果中看不中用。再比如:

reverseString(2);

这次说split不是一个函数,QAQ,太惨了。所以,该怎么优化一下呢?下面是一个考虑异常情况的简单例子:

function reverseString(str){
    if(typeof str != "string"){
	throw "The function needs an arguments of String";
    }else if(str.length == 1){
	return str;
    }else{
    	return str.split("").reduce((prev, cur, index, array) => {return cur + prev});
    }
}
这里接近尾声了,如果大家还有别的办法,不妨分享一下,互相学习。文中如有错误或不当的地方,烦请指正!


你可能感兴趣的:(JavaScript,JavaScript,字符串,反转)