5.3 原始值包装类型
什么是原始值包装类型?
每当用到某个原始值的方法或属性时,后台都会创建一个相应原始包装类型的对象,从而暴露出操作原始值的 各种方法。这个对象只存在于当前这行代码,下一行代码使用对象时会重新创建一个这个类型的对象。
5.3.3 String
JavaScript 字符
JavaScript 字符串由 16 位码元(code unit)组成。对多数字符来说,每 16 位码元对应一个字符。它使用了两种 Unicode 编码混合的策略:UCS-2 和 UTF-16。对于可以采用 16 位编码 的字符(U+0000~U+FFFF),这两种编码实际上是一样的。
-
charAt():返回给定索引位置的字符,具体来说,这个方 法查找指定索引位置的 16 位码元,并返回该码元对应的字符
-
charCodeAt():查看指定码元的字符编码
-
fromCharCode()方法用于根据给定的 UTF-16 码元创建字符串中的字符。
例如:
console.log(String.fromCharCode(0x61, 0x62, 0x63, 0x64, 0x65)); // "abcde"
对大多数字符来说,用十六位码元足够。但对于更多的字符,则用到了两个十六位码元构成的代理对表示。
在 Unicode 中称为基本多语言平面(BMP)。为了 表示更多的字符,Unicode 采用了一个策略,即每个字符使用另外 16 位去选择一个增补平面。这种每个字符使用两个 16 位码元的策略称为代理对。
由于由两个 16 位码元表示而以上方法解析时是将一个16 位当做一个字符,所以无法正确解析代理对。
codePointAt(): charCodeAt()时类似,codePointAt()接收 16 位码元的索引并返回该索引 位置上的码点(code point)
-
码点是 Unicode 中一个字符的完整标识
-
注意:如果传入的码元索引并非代理对的开头,就会返回错误的码点。这种错误只有检测单个字符 的时候才会出现
let message = "ab☺de"; console.log(message.codePointAt(1)); // 98 console.log(message.codePointAt(2)); // 128522 console.log(message.codePointAt(3)); // 56842 console.log(message.codePointAt(4)); // 100
它可以通过从左到右按正确的码元数遍历字符串来规避。迭代字符串可以智能地识别代 理对的码点。
console.log([..."ab☺de"]); // ["a", "b", "☺", "d", "e"]
fromCodePoint():法接收任意数量的码点,返回对应字符拼接起来的字符串
console.log(String.fromCodePoint(97, 98, 128522, 100, 101)); // ab☺de
normalize()方法:字符规范化
某些 Unicode 字符可以有多种编码方式。有的字符既可以通过一个 BMP 字符表示,也可以通过一 个代理对表示。通过不同编码表示的字符互不相等,因为比较操作符不在乎字符看起来是什么样的。
为解决这个问题,Unicode提供了 4种规范化形式,可以将类似上面的字符规范化为一致的格式,无论 底层字符的代码是什么。这 4种规范化形式是:NFD(Normalization Form D)、NFC(Normalization Form C)、 NFKD(Normalization Form KD)和 NFKC(Normalization Form KC)。可以使用 normalize()方法对字 符串应用上述规范化形式,使用时需要传入表示哪种形式的字符串:“NFD”、“NFC”、“NFKD"或"NFKC”
字符串操作方法
-
contact():连接字符串
-
提取字符串
-
slice()
- 参数:slice(开始位置,结束位置)
- 当参数为负数时,为负数的参数被视作 负数 + 字符串长度
-
substr()
-
参数:substr(开始位置,结束位置)
-
当参数为负数时,为负数的参数被视作0
let stringValue = "hello world"; console.log(stringValue.substr(3, -4)); // "" (empty string)
-
-
substring()
-
参数:substring(开始位置,提取个数)
-
当第一个参数为负数时,参数被视作 负数 + 字符串长度
-
当第二个参数为负数时,参数被视作 0
let stringValue = "hello world"; console.log(stringValue.substring(3, -4)); // "hel"
-
-
字符串位置方法
-
indexOf():从字符串开头查找子字符串,返回索引,未找到则为-1
-
lastIndexOf():从字符串结尾查找子字符串,返回索引,未找到则为-1
-
这两个方法都可以接收可选的第二个参数,表示开始搜索的位置。
let stringValue = "hello world"; console.log(stringValue.indexOf("o", 6)); // 7 console.log(stringValue.lastIndexOf("o", 6)); // 4
字符串包含方法
- startsWith():检查开始于索引 0 的匹配项,法接收可选的第二个参数,表示开始搜索的位置。
- endsWith():检查开始于索 引(string.length - substring.length)的匹配项,接收可选的第二个参数,表示应该当作字符串末尾的位置。
- includes():检查整个字符串,法接收可选的第二个参数,表示开始搜索的位置。
- 这些方法都会从字符串中搜索传入的字符串,并返回一个表示是否包含 的布尔值。它们的区别在于索引开始的位置不同。它们均可指定开始搜索或者结束的位置。
trim()方法
-
返回删除字符串前后空格的副本
例如:
let stringValue = " hello world "; let trimmedStringValue = stringValue.trim(); console.log(stringValue); // " hello world " console.log(trimmedStringValue); // "hello world"
-
另:
- trimLeft():从开头开始清理空格
- trimRight():从结尾开始清理空格
repeat()方法
-
这个方法接收一个整数参数,表示要将字符串复制多少次,然后返回拼接所有副本后的结果。
例如:
let stringValue = "na "; console.log(stringValue.repeat(16) + "batman"); // na na na na na na na na na na na na na na na na batman //呐 呐 呐 呐 呐 呐 呐
padStart()和 padEnd()方法
- padStart()和 padEnd()方法会复制字符串,如果小于指定长度,则在相应一边填充字符,直至 满足长度条件。
- 参数:(指定长度,填充字符),如果提供了多个字符的字符串,则会将其拼接并截断以匹配 指定长度。当长度足够时则不填充。
字符串迭代与解构
- 字符串的原型上暴露了一个@@iterator 方法,表示可以迭代字符串的每个字符。
字符串大小写转换
- toLowerCase(),toUpperCase()
- toLocaleLowerCase()和 toLocaleUpperCase():基于特定地区实现
字符串模式匹配方法
- String 类型专门为在字符串中实现模式匹配设计了几个方法。第一个就是 match()方法,这个方 法本质上跟 RegExp 对象的 exec()方法相同。match()方法接收一个参数,可以是一个正则表达式字 符串,也可以是一个 RegExp 对象。
localeCompare()方法
-
这个方法比较两个字符串,返回如下 3 个值中的一个
- 1(也可能是大于0的数字):如果按照字母表顺序,字符串应该排在字符串参数后头,则返回正值
- 0:字符串参数与字符串相等相等
- -1(也可能是小于0的数字):如果按照字母表顺序,字符串应该排在字符串参数前头,则返回负值
-
因为返回的具体值可能因具体实现而异,所以最好像下面的示例中一样使用 localeCompare():
function determineOrder(value) { let result = stringValue.localeCompare(value); if (result < 0) { console.log(`The string 'yellow' comes before the string '${value}'.`); } else if (result > 0) { console.log(`The string 'yellow' comes after the string '${value}'.`); } else { console.log(`The string 'yellow' is equal to the string '${value}'.`); } } determineOrder("brick"); determineOrder("yellow"); determineOrder("zoo");
-
localeCompare()的独特之处在于,实现所在的地区(国家和语言)决定了这个方法如何比较字符串。对于中文来说,通过拼音来排序(阿啵呲嘚…)。一般来说中文在英文后面。英文大写在前小写在后。
例如:
let stringValue = "啊啊啊啊" console.log(stringValue.localeCompare("aaaaaaa"))//-1 console.log(stringValue.localeCompare("bbbbbbb"))//-1