为了方便操作基本数据类型,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()
方法会将所有负参数值都转换为 0let 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()检查整个字符串:
startsWith()和 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
endsWith()方法接收可选的第二个参数,表示应该当作字符串末尾的位置。如果不提供这个参数,那么默认就是字符串长度。如果提供这个参数,那么就好像字符串只有那么多字符一样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
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. 字符串大小写转换
- toLowerCase()和toUpperCase()方法是原来就有的方法,与 java.lang.String 中的方法同名。
- 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。通常,如果不知道代码涉及什么语言,则最好使用地区特定的转换方法。