1. 为了方便操作基本数据类型,JavaScript 还提供了三个特殊的引用类型:`String``Number` `Boolean`<br />基本包装类型就是把简单数据类型包装成为复杂数据类型,这样基本数据类型就有了属性和方法。

9.1 String

要创建一个 String 对象,使用 String 构造函数并传入一个数值

let arr = new String('yuan mou')

String 对象的方法可以在所有字符串原始值上调用。3个继承的方法 valueOf()、toLocaleString()和 toString()都返回对象的原始字符串值。


每一个String对象都有一个length属性,用来表示字符串中字符的数量

let objectString = 'wo shi song mou'
console.log(objectString.length); //15

字符串的不可变

指的是里面的值不可变,虽然看上去可以改变内容,但其实是地址变了,内存中新开辟了一个内存空间。
  • 当重新给字符串变量赋值的时候,变量之前保存的字符串不会被修改,依然在内存中重新给字符串赋值,会重新在内存中开辟空间,这个特点就是字符串的不可变。
  • 由于字符串的不可变,在大量拼接字符串的时候会有效率问题

1. charAt()方法

charAt()方法返回给定索引位置的字符,由传给方法的整数参数指定。具体来说,这个方法查找指定索引位置的 16 位码元,并返回该码元对应的字符:

let name = "song"; 
console.log(name.charAt(2)); // "n"

简单来说,charAt()方法返回的是括号里选中元素在字符串中的位置(位置排序和数组相同,从0开始)

例子:提取出字符串中每种字符,并显示出现次数

let a = 'asfagsddagsfdasdasfsgdwgrfghhkhjthcjfgyyhbjutggyyj'
var o={};
for (let i=0 ; i<a.length;i++){  //遍历字符串,
let chart = a.charAt(i);            //使用charAt()函数提前每个字符
//o[chart]里由于chart里装载字符在变,不适合加‘’来定死
   if(o[chart]){                                    //if语句提取到underfined 转换成false执行
       o[chart]++;                                //if(k in o){      通过 in 判断k变量是否在o对象里    
      }else                                                //o[k]++ }          在就自加
     {o[chart]=1;}                                //else{ o[k]=1}            不在就赋值1
   }
console.log(o);
        //遍历对象,取出出现最对的字符及其次数
    let max = 0,
        car='',
        carsh=[];
    for (let k in o){
        if(o[k]>max){
           max=o[k];
           char = k;
          }
        carsh.push([k,o[k]])
    }
console.log('出现次数最多的是'+char+'出现次数为'+max);
console.log(carsh);
console.log('----------');
let kk = Array.from(carsh)   //使用fro()进行浅复制,用于改变carsh排列方式
console.log(kk.sort());

2. charCodeAt()方法

使用 charCodeAt()方法可以查看指定码元的字符编码。这个方法返回指定索引位置的码元值,索引以整数指定

let message = "abcde"; 
// Unicode "Latin small letter C"的编码是 U+0063 
console.log(message.charCodeAt(2)); // 99 
// 十进制 99 等于十六进制 63 
console.log(99 === 0x63); // true

3. 字符串操作方法

1. concat()方法

将一个或多个字符串拼接成一个字符串

let one = "song "; 
let tow = one.concat("qi ",'wen'); 
console.log(tow); // "song qi wen" 
console.log(stringValue); // "song"
  • concat()方法可以添加不止一个字符串
  • 拼接完原本字符串不会改变
  • 效率太低,还没有“+”速度块,而且多数情况下,对于拼接多个字符串来说,使用加号更方便。

提取字符串

ECMAScript 提供了 3 个从字符串中提取子字符串的方法:slice()substr()substring()。这3个方法都返回调用它们的字符串的一个子字符串,而且都接收一或两个参数。

  • 第一个参数表示子字符串开始的位置,第二个参数表示子字符串结束的位置。对 slice()substring()而言,第二个参数是提取结束的位置(即该位置之前的字符会被提取出来)。
  • substr()而言,第二个参数表示返回的子字符串数量。任何情况下,省略第二个参数都意味着提取到字符串末尾。
  • concat()方法一样,slice()substr()substring()也不会修改调用它们的字符串,而只会返回提取到的原始新字符串值。
let stringValue = "hello world"; 
console.log(stringValue.slice(3)); // "lo world" 
console.log(stringValue.substring(3)); // "lo world" 
console.log(stringValue.substr(3)); // "lo world" 
console.log(stringValue.slice(3, 7)); // "lo w" 
console.log(stringValue.substring(3,7)); // "lo w" 
console.log(stringValue.substr(3, 7)); // "lo worl"
  • 在这个例子中,slice()substr()substring()是以相同方式被调用的,而且多数情况下返回的值也相同。
  • 如果只传一个参数 3,则所有方法都将返回”lo world”,因为”hello”中”l”位置为 3。
  • 如果传入两个参数 3 和 7,则``slice()substring()返回”lo w”(因为”world”中”o”在位置 7,不包含),而 substr()返回”lo worl”,因为第二个参数对它而言表示返回的字符数。
  • 当某个参数是负值时,这 3 个方法的行为又有不同。比如,slice()方法将所有负值参数都当成字符串长度加上负参数值。而 substr()方法将第一个负参数值当成字符串长度加上该值,将第二个负参数值转换为 0。
  • substring()方法会将所有负参数值都转换为 0

    let stringValue = "hello world"; 
    console.log(stringValue.slice(-3)); // "rld" 
    console.log(stringValue.substring(-3)); // "hello world" 
    console.log(stringValue.substr(-3)); // "rld" 
    console.log(stringValue.slice(3, -4)); // "lo w" 
    console.log(stringValue.substring(3, -4)); // "hel" 
    console.log(stringValue.substr(3, -4)); // "" (empty string)
    
  • 这个例子明确演示了 3 个方法的差异。在给slice()substr()传入负参数时,它们的返回结果相同。这是因为-3 会被转换为 8(长度加上负参数),实际上调用的是 slice(8)和 substr(8)。而substring()方法返回整个字符串,因为-3 会转换为 0。

  • 在第二个参数是负值时,这 3 个方法各不相同。slice()方法将第二个参数转换为 7,实际上相当于调用 slice(3, 7),因此返回”lo w”。
  • substring()方法会将第二个参数转换为 0,相当于调用substring(3, 0),等价于 substring(0, 3),这是因为这个方法会将较小的参数作为起点,将较大的参数作为终点。
  • substr()来说,第二个参数会被转换为 0,意味着返回的字符串包含零个字符,因而会返回一个空字符串。

4. 字符串位置方法

有两个方法用于在字符串中定位子字符串:indexOf()和 lastIndexOf()。

  • 这两个方法从字符串中搜索传入的字符串,并返回位置(如果没找到,则返回-1)。
  • 两者的区别在于,indexOf()方法从字符串开头开始查找子字符串,而 lastIndexOf()方法从字符串末尾开始查找子字符串
    let stringValue = "hello world"; 
    console.log(stringValue.indexOf("o")); // 4 
    console.log(stringValue.lastIndexOf("o")); // 7
    

5. replace()方法

replace() 方法用于在字符串中用一些字符替换另一些字符,其使用格式如下:

字符串名.replace(被替换的字符串, 要替换为的字符串);

6. split()方法

split()方法用于切分字符串,它可以将字符串切分为数组。在切分完毕之后,返回的是一个新数组。
通过字符串内的符号对字符串进行切割

字符串名.split("分割字符")
let arr=["name=yuanmou"]
let newArr=arr.split('=')
console.log(newArr)   //['name','yuanmou']

7. repeat()方法

这个方法接收一个整型参数,表示要将字符串复制多少次,然后返回拼接所有副本的结果

let stringValue = "na "; 
console.log(stringValue.repeat(10) + "batman"); 
//na na na na na na na na na na batman

8. trim()方法

创建一个字符串副本,将副本内的字符串前后所有空格都删除,再返回副本

let stringValue = "  hello w or ld  "; 
let trimmedStringValue = stringValue.trim(); 
console.log(stringValue); // "  hello w or ld  " 
console.log(trimmedStringValue); // "hello w or ld"

9. 字符串包含方法

ECMAScript 6 增加了 3 个用于判断字符串中是否包含另一个字符串的方法:

  • startsWith()、endsWith()和 includes()。
  • 这些方法都会从字符串中搜索传入的字符串,并返回一个表示是否包含的布尔值。
  • 它们的区别在于:
    • startsWith()检查开始于索引 0 的匹配项,
    • endsWith()检查开始于索引(string.length - substring.length)的匹配项,
    • includes()检查整个字符串:
      let message = "foobarbaz"; 
      console.log(message.startsWith("foo")); // true 
      console.log(message.startsWith("bar")); // false 
      console.log(message.endsWith("baz")); // true 
      console.log(message.endsWith("bar")); // false 
      console.log(message.includes("bar")); // true 
      console.log(message.includes("qux")); // false
      
      startsWith()和 includes()方法接收可选的第二个参数,表示开始搜索的位置。如果传入第二 个参数,则意味着这两个方法会从指定位置向着字符串末尾搜索,忽略该位置之前的所有字符。下面是 一个例子:
      let message = "foobarbaz"; 
      console.log(message.startsWith("foo")); // true 
      console.log(message.startsWith("foo", 1)); // false 
      console.log(message.includes("bar")); // true 
      console.log(message.includes("bar", 4)); // false
      
      endsWith()方法接收可选的第二个参数,表示应该当作字符串末尾的位置。如果不提供这个参数,那么默认就是字符串长度。如果提供这个参数,那么就好像字符串只有那么多字符一样
      let message = "foobarbaz"; 
      console.log(message.endsWith("bar")); // false 
      console.log(message.endsWith("bar", 6)); // true 从索引6位置开始从后往前正好有“bar”
      

10. padStart()和padEnd()方法

padStart()和 padEnd()方法会复制字符串,如果小于指定长度,则在相应一边填充字符,直至 满足长度条件。这两个方法的第一个参数是长度,第二个参数是可选的填充字符串,默认为空格( U+0020)。

let str = "foo"; 
console.log(str.padStart(6)); // "   foo" 填充了3个空格
console.log(str.padStart(9, ".")); // "......foo" 
console.log(str.padEnd(6)); // "foo   " 
console.log(str.padEnd(9, ".")); // "foo......"

可选的第二个参数并不限于一个字符。如果提供了多个字符的字符串,则会将其拼接并截断以匹配 指定长度。此外,如果长度小于或等于字符串长度,则会返回原始字符串。

let str = "foo"; 
console.log(str.padStart(8, "bar")); // "barbafoo" 
console.log(str.padStart(2)); // "foo" 
console.log(str.padEnd(8, "bar")); // "foobarba" 
console.log(str.padEnd(2)); // "foo"

11. 字符串模式匹配方法

String 类型专门为在字符串中实现模式匹配设计了几个方法。

  • 第一个就是 match()方法,这个方法本质上跟 RegExp 对象的 exec()方法相同。
  • match()方法接收一个参数,可以是一个正则表达式字符串,也可以是一个 RegExp 对象。 ```javascript let text = “cat, bat, sat, fat”; let pattern = /.at/;

// 等价于 pattern.exec(text) let matches = text.match(pattern); console.log(matches.index); // 0 console.log(matches[0]); // “cat” console.log(pattern.lastIndex); // 0

match()方法返回的数组与 RegExp 对象的 exec()方法返回的数组是一样的:第一个元素是与整个模式匹配的字符串,其余元素则是与表达式中的捕获组匹配的字符串(如果有的话)。

---

另一个查找模式的字符串方法是 search()。

- 这个方法唯一的参数与 match()方法一样:
      - 正则表达式字符串或 RegExp 对象。
      - 这个方法返回模式第一个匹配的位置索引,如果没找到则返回1。
      - search()始终从字符串开头向后匹配模式。
```javascript
let text = "cat, bat, sat, fat"; 
let pos = text.search(/at/); 
console.log(pos); // 1

这里,search(/at/)返回 1,即”at”的第一个字符在字符串中的位置


12. 字符串大小写转换

  1. toLowerCase()和toUpperCase()方法是原来就有的方法,与 java.lang.String 中的方法同名。
  2. toLocaleLowerCase()和 toLocaleUpperCase()方法旨在基于特定地区实现。
    let str = "hello world"; 
    console.log(str.toLocaleUpperCase()); // "HELLO WORLD" 
    console.log(str.toUpperCase()); // "HELLO WORLD" 
    console.log(str.toLocaleLowerCase()); // "hello world" 
    console.log(str.toLowerCase()); // "hello world"
    
    这里,toLowerCase()toLocaleLowerCase()都返回 hello world,而 toUpperCase()toLocaleUpperCase()都返回 HELLO WORLD。通常,如果不知道代码涉及什么语言,则最好使用地区特定的转换方法