白菜刷LeetCode记-344. Reverse String

开始尝试用JavaScript来刷LeetCode,对前端又白又菜,那这次刷题就直接叫白菜的刷LeetCode旅程了。

今天的题目是很简单的字符串首尾交换,题目如下:

一开始自己的代码如下:

 1 /**
 2  * @param {string} s
 3  * @return {string}
 4  */
 5 var reverseString = function(s) {
 6     let i = 0, j = s.length - 1, tmp;
 7     while(i < j){
 8         tmp = s[i];
 9         s[i] = s[j];
10         s[j] = tmp;
11         i++;
12         j--;
13     }
14     
15     return s;
16 };

当然这样做得到的结果是错误的,输出的结果跟原来一样,也就是“hello”经过自己代码后还是"hello"。

看了一下讨论区,具体的方法是先将字符串转化为数组,然后对数据进行反转,最后再拼接在一起,代码如下:

 1 /**
 2  * @param {string} s
 3  * @return {string}
 4  */
 5 var reverseString = function(s) {
 6    
 7     const arr = s.split('');
 8     
 9     for(let i = 0, j = s.length - 1 ; i < j ; i++, j--){
10         arr[i] = s[j];
11         arr[j] = s[i];
12     }
13     
14     return arr.join('');
15 };

还有一种直接调用数组自带的反转函数的方法,代码只需要一行,不仅对大神们于JavaScript自带函数的熟悉感到羡慕嫉妒恨啊,代码如下:

var reverseString = function(s) {
    return s.split('').reverse().join('');
};

感谢LeetCode讨论区大神们贡献的结果啊!

问题来了,为什么自己的代码会对原来数据没影响呢?

看了一下http://www.w3school.com.cn/jsref/jsref_obj_string.asp

里头有这么一段话:

需要注意的是,JavaScript 的字符串是不可变的(immutable),String 类定义的方法都不能改变字符串的内容。像 String.toUpperCase() 这样的方法,返回的是全新的字符串,而不是修改原始字符串。

在较早的 Netscape 代码基的 JavaScript 实现中(例如 Firefox 实现中),字符串的行为就像只读的字符数组。例如,从字符串 s 中提取第三个字符,可以用 s[2] 代替更加标准的 s.charAt(2)。此外,对字符串应用 for/in 循环时,它将枚举字符串中每个字符的数组下标(但要注意,ECMAScript 标准规定,不能枚举 length 属性)。因为字符串的数组行为不标准,所以应该避免使用它。

因此原来的代码的方法是错误的,因为JavaScript的字符串是不可变的,经过循环后,s还是原来的值。而且根据上面这段话,使用s[num]这种访问字符串中某一位字符的方法也是不规范的,应该用 s.charAt(num)来获取。

原文地址:https://www.cnblogs.com/sssysukww/p/9514397.html