JS的字符串

41 阅读10分钟

53、创建字符串

 * 创建字符串的方式
 *    1.字面量的形式创建字符串
 *        var str = 'abc'
 *    2.内置构造函数的形式创建字符串
 ```js
      var str = new String() 
      //创建了一个字符串,但是是空字符
      console.log(str)
      
      var str = new String('abc') //创建了一个字符串
      console.log(str)
 ```

54、字符串的索引与下标

 * 字符串的length与下标
 * 
 *    length与下标的含义与数组中的一样
 *    length: 长度
 *    索引(下标):获取到字符串中指定位置的值
 *    注意:字符串中通过索引能够获取到指定位置的值,只不过获取到的值是只读的  
             换句话说 获取到的值,能看不能改
 ```js
     var str = 'abc'
     console.log(str.length) //3
     console.log(str[1]) //b
     
     str[1] = 'Q' 
     //因为字符串通过索引获取到的值是只读的,我们修改是没用的,所以这一行代码没意义
     console.log(str) //还是abc,无法修改
 ```

55、字符串的方法

(1).charAt
 * 语法:字符串.charAt(索引)
 * 作用:查询指定下标的值
 * 返回值:查询到的值,如果没有查询到就是一个空字符串
 ```js
     var str = 'abcd'
     var str1 = str.charAt(0)
     console.log(str1) //a
     var str2 = str.charAt(50)
     console.log(str2) //因为没有查询到,返回的是空字符串
 ```
(2).charCodeAt
 * 语法:字符串.charCodeAt(索引)
 * 作用:查询指定下标的值 对应的 十进制码
 * 返回值:查询到的值对应的十进制码 如果没有查询到会返回一个NaN
 ```js
     var str = 'abcd'
     var str1 = str.charCodeAt(0)
     console.log(str1) //字符串a的十进制码   97
     var str2 = str.charCodeAt(50)
     console.log(str2) //因为没有查询到 返回一个NaN
 ```
(3).toLowerCase
 * 语法:字符串.toLowerCase()
 * 作用:将这个字符串转换为小写
 * 返回值:转换后的字符串
 ```js
     var str1 = 'abcDEF'
     var str2 = 'QWER'
     var str3 = 'asdf'
     // var str4 = str1.toLowerCase()
     // console.log(str4)
     console.log(str1.toLowerCase()) //abcDEF  ->  abcdef
     console.log(str2.toLowerCase()) //QWER    ->  qwer
     console.log(str3.toLowerCase()) //asdf    ->  asdf
 ```
(4).toUpperCase
 * 语法:字符串.toUpperCase
 * 作用:将这个字符串转换为大写
 * 返回值:转换后的字符串
 ```js
     var str1 = 'abcDEF'
     var str2 = 'QWER'
     var str3 = 'asdf'
     // var str4 = str1.toUpperCase()
     // console.log(str4)
     console.log(str1.toUpperCase()) //abcDEF  ->  ABCDEF
     console.log(str2.toUpperCase()) //QWER    ->  QWER
     console.log(str3.toUpperCase()) //asdf    ->  ASDF
 ```
 * 
(5).substr
 * 语法:字符串.substr(开始索引, 多少个)
 * 作用:截取指定的字符串
 * 返回值:截取到的字符串
 * 注意:mnd说明这个方法将来某一天可能会删除,所以建议我们使用substring
 ```js
     var str = 'qwertyuiop'
     var str1 = str.substr(0, 3) 
     //从下标0开始,截取3个,其实应该 就是下标0,1,2的值
     console.log(str1) //qwe
     var str1 = str.substr(3, 2) 
     //从下标3开始,截取2个,其实应该 就是下标3,4的值
     console.log(str1) //rt
 ```
(6).substring
 * 语法:字符串.substring(开始索引, 结束下标)
 * 作用:截取指定的字符串
 * 返回值:截取到的字符串
 * 注意:
 *    1.参数包前不包后
 *    2.结束索引可以不写,相当于写了length(字符串的总长度)
 ```js
     var str = 'qwertyuiop'
     var str1 = str.substring(0, 3) //从下标0开始,到下标3结束
     console.log(str1) //qwe
     var str2 = str.substring(0) //从下标0开始,结束索引因为没有传递,所以默认是length,也就是从下标0开始,一直到字符串最后
     console.log(str2) //qwertyuiop
 ```
(7).slice
 * 语法:字符串.slice(开始索引, 结束索引)
 * 作用:截取指定字符串
 * 返回值:截取到的字符串
 * 注意:
 *    1.参数包前不包后
 *    2.结束索引可以不写,相当于写了length(字符串的总长度)
 *    3.开始索引可以不写,相当于写了0
 *    4.结束索引支持写负数,相当于length +负数
 ```js
     var str = 'qwertyuiop'
     var str1 = str.slice(0, 3) //从下标0开始,到下标3结束
     console.log(str1) //qwe
     var str2 = str.slice(0) 
     //从下标0开始,因为没写结束索引,所以默认为length
     console.log(str2) //qwertyuiop
     var str3 = arr.slice() 
     //开始索引不写,默认为0,结束索引不写,默认为length
     console.log(str3) //qwertyuiop
     var str4 = str.slice(0, -3) 
     //从下标0开始,到下标length-3结束
     console.log(str4) //qwertyu
 ```
(8).concat
 * 语法:字符串.concat(数据1, 数据2, 数据3...)
 * 作用:将字符串和参数传递的数据 进行拼接
 * 返回值:拼接后的字符串
 ```js
     var str = 'qwer'
     var str1 = str.concat('@', '+', '!')
     console.log(str1) //qwer@+!
 ```
 * 
(9).indexOf
 * 语法:字符串.indexOf(数据, 开始下标)
 * 作用:寻找数据在字符串中的位置
 * 返回值:找到的时候返回下标,找不到返回-1
 * 注意:第二个参数可以不传递,默认为0
 ```js
     var str = 'qwer'
     var str1 = str.indexOf('q', 1) 
     //在字符串str中,下标1的位置,开始查找字符串'q'
     console.log(str1) //-1
     var str1 = str.indexOf('q', 0) 
     //在字符串str中,下标0的位置,开始查找字符串'q'
     console.log(str1) //0
     var str1 = str.indexOf('q') 
     //在字符串str中,下标0的位置,开始查找字符串'q'
     console.log(str1) //0
 ```
 * 
(10).lastIndexOf
 * 语法:字符串.lastIndexOf(数据, 开始索引)
 * 作用:寻找数据在字符串中的位置(从后往前/从右向左)
 * 返回值:找到的时候返回下标,找不到返回-1
 * 注意:第二个参数可以不传递,默认为length - 1
 ```js
     var str = 'qwer'
     var str1 = str.lastIndexOf('e', 1) 
     //在字符串str中,下标1的位置,开始查找字符串'e'
     console.log(str1)//-1
     var str1 = str.lastIndexOf('e') 
     //在字符串str中,下标1的位置,开始查找字符串'e'
     console.log(str1)//2
 ```
 * 
(11).split
 * 语法:字符串.split('符号')
 * 作用:在字符串中找到'符号' 然后将这个字符串分隔,并放在一个数组内
 * 返回值:一个数组
 * 注意:参数如果传递的是 空字符串('') 会将字符串全部分隔开
 ```js
     var str = 'qwer, tyui, asdf, ghjk'
     console.log('原始字符:', str)
     
     var str1 = str.split(',')
     // 通过, 将字符串str分隔到一个数组中
     console.log(str1) //['qwer', ' tyui', ' asdf', ' ghjk']
     
     var str2 = str.split('i')
     // 通过i 将字符串str分隔到一个数组中
     console.log(str2) //['qwer, tyu', ', asdf, ghjk']
     
     var str3 = str.split(' ')
     // 通过一个空格 将字符串str分隔到一个数组中
     console.log(str3) //['qwer,', 'tyui,', 'asdf,', 'ghjk']
     
     var str4 = str.split('')// 通过一个空字符串 将字符串str分隔到一个数组中
     console.log(str4) 
     // ['q', 'w', 'e', 'r', ',', ' ', 't', 'y', 'u', 'i', ',', ' ', 'a', 's', 'd', 'f', ',', ' ', 'g', 'h', 'j', 'k']
     
     var str5 = str.split('@')// 通过一个@ 将字符串str分隔到一个数组中
     console.log(str5) //['qwer, tyui, asdf, ghjk']
 ```
!(12).trim
 * 语法:字符串.trim()
 * 作用:去掉字符串两侧的空格
 * 返回值:去掉空格后的字符串
 ```js
     var str = ' a b c '
     console.log('原始的字符串:', str)
     var str1 = str.trim()
     console.log(str1) //a b c
 ```
(13).trimStart / trimLeft
 * 语法:字符串.trimStart() / 字符串.trimLeft()
 * 作用:去掉字符串开始(左侧)的空格
 * 返回值:去掉空格后的字符串
 ```js
     var str = ' a b c '
     console.log('原始的字符串:', str)
     
     var str1 = str.trimStart()
     var str2 = str.trimLeft()
     console.log(str1) //a b c 
     console.log(str2) //a b c 
 ```
 * 
(14).trimEnd / trimRight
 * 语法:字符串.trimEnd() / 字符串.trimRight()
 * 作用:去掉字符串结束(右侧)的空格
 * 返回值:去掉空格后的字符串
 ```js
     var str = ' a b c '
     console.log('原始的字符串:', str)
     
     var str1 = str.trimEnd()
     var str2 = str.trimRight()
     console.log(str1) // a b c
     console.log(str2) // a b c
 ```
!(15).includes
 * 语法:字符串.includes(字符串片段)
 * 作用:判断 当前字符串中,是否拥有指定字符串片段
 * 返回值:一个布尔值
 *        true -> 拥有
 *        false -> 没有
 ```js
     var str = 'qwertyuiop'
     var str1 = str.includes('tyui')
     console.log(str1) //true
     var str2 = str.includes('tyuip')
     console.log(str2) //false
 ```
(16).startsWith
 * 语法:字符串.startsWith(字符串片段)
 * 作用:判断 字符串开头 是不是指定的字符串片段
 * 返回值:一个布尔值
 *        true -> 是开头
 *        false -> 不是开头
 ```js
     var str = 'qwertyuiop'
     var str1 = str.startsWith('qwer')
     console.log(str1) //true
     var str2 = str.startsWith('wer')
     console.log(str2) //false
 ```
(17).endsWith
 * 语法:字符串.endsWith(字符串片段)
 * 作用:判断 字符串结尾 是不是指定的字符串片段
 * 返回值:一个布尔值
 *        true -> 是结尾
 *        false -> 不是结尾
 ```js
     var str1 = str.endsWith('op')
     console.log(str1) //true
     var str2 = str.endsWith('qwer')
     console.log(str2) //false
 ```
(18).replace
 * 语法:字符串.replace('要被替换的字符', '替换的字符')
 * 作用:找到当前字符串中第一个参数对应的值,然后将其替换为第二个参数
 * 返回值:替换完成的字符串
 ```js
     var str = 'abcdefg'
     var str1 = str.replace('abc', '@@!!##')
     console.log(str1) //@@!!##defg
     var str2 = str.replace('qwer', '@@!!##')
     console.log(str2) //abcdefg
 ```

56、课堂案例(面试题)

* 一道面试题
 *  统计字符串中每个字符串出现的次数(以对象的形式存储)
    // 半成品
    var str = 'aaabbbccddeeeea'
    var obj = {}
   //  通过循环拿到字符串中每个位置的值
   for(var i = 0; i <= str.length; i++) {
     // console.log(str[i])
     var key = str[i]
     if(obj[key] === undefined) {
       /**
        * obj -> 全局声明的空对象
        * key -> 在循环内部创建的一个变量,内部的值 就是 str[i]
        * str[i] -> 字符串对应下标的值
        * 
        * 第一轮循环  i === 0   str[i] === a   key === a
        *    obj[key] -> obj['a'] -> 此时得到的值应该是undefined
        * */ 
       obj[key] = 1
     }
   }
   /**
    * 第1轮
    *    i === 0    str[i] === 'a'   key === 'a'   obj = {}
    * 
    *        obj[key] === undefined  obj[key]  ->  obj['a']  ->  undefined
    *        if 条件成立,obj[key] = 1 -> obj['a'] = 1
    *        第1轮结束后的 obj === {a: 1}
    * 第2轮
    *    i === 1    str[i] === 'a'   key === 'a'   obj = {a: 1}
    * 
    *        obj[key] === undefined  obj[key]  ->  obj['a']  ->  1
    *        if 条件不成立,开始下一轮循环
    *        第2轮结束后的 obj === {a: 1}
    * 第3轮
    *    i === 2    str[i] === 'a'   key === 'a'   obj = {a: 1}
    * 
    *        obj[key] === undefined  obj[key]  ->  obj['a']  ->  1
    *        if 条件不成立,开始下一轮循环
    *        第3轮结束后的 obj === {a: 1}
    * 第4轮
    *    i === 3    str[i] === 'b'   key === 'b'   obj = {a: 1}
    * 
    *        obj[key] === undefined  obj[key]  ->  obj['b']  ->  undefined
    *        if 条件成立,obj[key] = 1 -> obj['b'] = 1
    *        第4轮结束后的 obj === {a: 1, b: 1}
    * */  
    console.log(obj)
    //  基础版
    var str = 'aaabbbccddeeeea'
    var obj = {}
    for(var i = 0; i <= str.length; i++) {
      // console.log(str[i])
      var key = str[i]
      if(obj[key] === undefined) {
        obj[key] = 1
      } else {
        obj[key]++
      }
    }
    console.log(obj)
    /**
     * 第1轮
     *     i === 0    str[i] === 'a'   key === 'a'   obj = {}
     *        obj[key] === undefined  obj[key]  ->  obj['a']  ->  undefined
     *        if 条件成立,执行if分支,else分支不再执行 
     *        obj[key] = 1 -> obj['a'] = 1
     *        第1轮 循环结束后 obj === {a: 1}
     * 第2轮
     *     i === 1    str[i] === 'a'   key === 'a'   obj = {a: 1}
     *        obj[key] === undefined  obj[key]  ->  obj['a']  ->  1
     *        if 条件不成立,不执行if分支,else分支执行 
     *        obj[key]++ -> obj['a']++
     *        第2轮 循环结束后 obj === {a: 2}
     * 第3轮
     *     i === 2    str[i] === 'a'   key === 'a'   obj = {a: 2}
     *        obj[key] === undefined  obj[key]  ->  obj['a']  ->  2
     *        if 条件不成立,不执行if分支,else分支执行 
     *        obj[key]++ -> obj['a']++
     *        第3轮 循环结束后 obj === {a: 3}
     * 第4轮
     *     i === 3    str[i] === 'b'   key === 'b'   obj = {a: 3}
     *        obj[key] === undefined  obj[key]  ->  obj['b']  ->  undefined
     *        if 条件成立,执行if分支,else分支不再执行 
     *        obj[key] = 1 -> obj['b'] = 1
     *        第4轮 循环结束后 obj === {a: 3, b: 1}
     * */ 
    // 优化版
    var str = 'aaabbbccddeeeea'
    var obj = {}
    for(var i = 0; i <= str.length; i++) { 
      // var key = str[i]
      // if(obj[str[i]] === undefined) {//obj[str[i]] =-= undefined 的时候做某些事
      if(!obj[str[i]]) {
        /**
         * 因为undefined 转换为布尔值是false,
         * 
         * 所以如果obj[str[i]]的值就是undefined的时候
         *    那么布尔值就是false,加一个!代表取反,所以实际得到的布尔值 是true
         * 
         * obj[str[i】]要么是undefined要么是从1开始的数字
         *    所以除了是undefined之外的其他情况他的布尔值都是true
         *    加一个!代表取反,所以实际的到的布尔值为false
         * */ 
        obj[str[i]] = 1
      } else {
        obj[str[i]]++
      }
    }
    console.log(obj)
    // 最终版本
    var str = 'aaabbbccddeeeea'
    var obj = {}
    for(var i = 0; i <= str.length; i++) { 
      if(!obj[str[i]]) {
        obj[str[i]] = 1
      } else {
        obj[str[i]]++
      }
    }
    console.log(obj)

57、课后练习

* ①. 反转字符串
 * var str = 'abcdef'
 * 代码处理后的 str === fedcba
 ```js
     // 方法1
     var str = 'abcdef'
     // var newStr = str.split('')
     // var newStr2 = newStr.reverse()
     // var newStr3 = newStr2.join('')
     var newStr = str.split('').reverse().join('')
     console.log(newStr3)
     
     // 方法2
     var newStr = '';
     for(var i = 0; i <= str.length; i++) {
         var s = str.charAt(str.length-i-1)
         newStr += s
     }
     console.log(newStr)
 ```
* ②.查询字符串
JS 中内把字符串分为几种类型(约定)
1. 普通字符串: '123asd阿松大'
2. 数字字符串: '123123123123123'
3. html格式字符串: '<p></p>'
4. 查询字符串: 'key=value&key2=value2&key3=value3'
    * 一条数据: key=value
    * 多条数据: & 符间隔
假设 str 存储的是后端反馈给我们的一个信息
var str = 'username=靓仔&age=18&qq=88888888'
需求1:
将'username=靓仔&age=18&qq=88888888'
更改为
{
    username: '靓仔',
    age: 18,
    qq: 88888888
}
需求2:
将
{
    username: '靓仔',
    age: 18,
    qq: 88888888
}
更改为
'username=靓仔&age=18&qq=88888888'
```js
    // 需求1 字符串转对象
    var str = 'username=靓仔&age=18&qq=88888888'
    var obj = {}
    /**
    * 分析:
    *    1.拿到字符串中所有的key
    *    2.拿到字符串中所有的key对应的value
    * 
    * 逻辑:
    *    1.将字符串分割为key=value (分割完应该会有3个)
    *    2.拿到每一个key 添加到对象中,并且给值赋值为对应的vaLue
    * */ 
    //  1.将字符串分割为key=value (分割完应该会有3个)
    var arr = str.split('&')
    //  console.log(arr)
    //  2.拿到每一个key添加到对象中,并且给值赋值为_对应的value
    // 2.1遍历数组拿到数组的每一项,也就是每一个 key=value
    arr.forEach(function(item) {
        var itemInfo = item.split('=')
        /**
        * console.log(itemInfo)
        * ['username', '靓仔']
        * ['age', '18']
        * ['qq', '88888888']
        * var key = itemInfo[0]
        * var value = itemInfo[1]
        * obj[key] = value
        * */ 
        obj[itemInfo[0]] = itemInfo[1] //向对象内存储
    })
    
    // 需求2 将对象转换为 字符串
    console.log(obj)
    var newStr = ''
    /**
    * obj === {
        username: '靓仔',
        age: 18,
        qq: 88888888
    }
    * 需要将他转换为一个字符串'username=视仔&age=18&qq=88888888'
    * 核心:拿到对象的所有key 与value,然后拼接到一个字符串中
    * */ 
    for (var k in obj) {
        newStr += k + '=' + obj[k] + '&'
    }
    console.log(newStr)// 此时结尾多一个 &
    newStr = newStr.slice(0, -1)
    console.log(newStr)
```