基本包装类型
基本包装类型是 特殊的 引用类型
ECMAScript 提供了三种基本包装类型 Number String Boolean
每当读取一个基本类型值的时候,后台就会创建一个对应的基本包装类型的对象,从而可以调用属性、方法来进行后续操作
| javascript 引擎后台创建了对应基本包装类型的实例(对象) |
| |
| 每当读取一个基本类型值的时候,后台就会创建一个对应的基本包装类型对象 |
| |
| 1、创建 String 类型 实例 |
| |
| 2、在实例上调用指定方法 |
| |
| 3、销毁这个实例 |
| |
| let str_1 = New String('caixin') |
| |
| let str_2 = str_1.substring(2) |
| |
| str_1 = null |
| |
| 由于基本包装类型 “会销毁” 的特性,短暂的生命周期, 这决定了我们不能为基本类型值添加自定义属性和方法。 |
| |
| const word = 'you are the best' |
| |
| word.name= 'john' |
| |
| console.log(word.age) => undefined |
引用类型 和 基本包装类型的区别
| 主要区别就是这两种对象的生命周期不同 |
| |
| 基本包装类型自动创建的对象在对象被调用的时刻存在,调用完后就被销毁了 |
| |
| 而使用 new 关键字创建的引用类型的实例,对象在当前作用域都存在 |
| |
| 基本包装类型对象 |
| |
| 1 var s = 'some'; |
| |
| 2 s.age = 'Joel'; |
| |
| 3 console.log(s.age); => undefined |
| |
| 4 typeof s => string |
| |
| 显示实例化包装类型 |
| |
| 1 var s = new String('some'); |
| |
| 2 s.age = 'Joel'; |
| |
| 3 console.log(s.age); => Joel |
| |
| 4 typeof s => object |
自动转换
| 在Number、String、Boolean 类型调用属性或方法的时候 JavaScript 引擎自动将其转为包装对象,在这个对象上调用其属性或方法。 |
| |
| 调用结束后,这个临时对象就会被销毁。这就叫原始类型与实例对象的自动转换 |
| |
| 这三个对象(Number、String、Boolean)作为构造函数使用(带有new)时,可以将原始类型的值转为对象 |
| |
| 作为普通函数使用时(不带有new),可以将任意类型的值,转为原始类型的值 |
创建字符串
| let str = 'hello world' |
| |
| let str1 = new String('hello world') |
| |
| 这两种方法的本质是相同的 |
| |
| 第一种声明也是通过第二种实现的 |
| |
| 字符串其实就是String对象的一个实例 |
字符串属性
| 常用属性只有一个:length,返回字符串的长度 |
| |
| let str = 'hello' |
| |
| console.log(str.length) => 5 |
字符串方法 API
以下 除了 String.raw() 为静态方法,其他都是字符串对象的方法
所有的字符串方法都不会对原字符串修改,都是返回一个新的字符串或结果
拼接 / 补全
concat()
| str.concat(string2, string3[, ..., stringN]) |
| |
| 将一个或多个字符串与原字符串依次拼接,形成一个新的字符串并返回 |
| |
| let str1 = "hello" |
| let str2 = " world" |
| |
| let str3 = str1.concat(str2) |
| console.log(str3) => hello world |
padStart() ( ES6 新增特性 )
| str.padStart(targetLength [, padString]) |
| |
| 从左边 开头 开始,使用给定字符串填充当前字符串,使得最终长度达到指定长度,超出的部分将被截断 |
| |
| 第一个参数: 指定字符串的最小长度 |
| 第二个参数: 补全的字符串 |
| |
| '1'.padStart(10,'0') => '0000000001' |
| |
| '123456'.padStart(10,'0') => '0000123456' |
| |
| '09-12'.padStart(10,'YYYY-MM-DD') => 'YYYY-09-12' |
| |
| console.log('abc'.padStart(10,'nihao')) => 'nihaoniabc' |
padEnd() ( ES6 新增特性 )
| str.padEnd(targetLength [, padString]) |
| |
| 从右边 结尾 开始,使用给定字符串填充当前字符串,使得最终长度达到指定长度,超出的部分将被截断 |
| |
| console.log('abc'.padEnd(8,'*')) => ' abc***** ' |
repeat()
| str.repeat(count) |
| |
| 重复当前字符串给定的次数,返回新字符串 |
| |
| 如果不给出 count,count 默认为 0 |
| |
| 如果 count 为 0,则返回一个空字符串 |
| |
| console.log('abc'.repeat()) => '' |
| |
| console.log('abc'.repeat(0)) => '' |
| |
| console.log('abc'.repeat(2)) => 'abcabc' |
| |
| console.log('abc'.repeat(3.7)) => 'abcabcabc' |
查询
startsWith()
| str.startsWith(searchString [, position]) |
| |
| 断原字符串是否是以另外一个给定的子字符串 “开头” |
| |
| position 表示开始查找的索引,默认为 0 |
| |
| 区分大小写 |
| |
| let str = 'hello' |
| console.log(str.startsWith('Hell')) => false |
endsWith()
| str.endsWith(searchString [, position]) |
| |
| 判断原字符串是否是以另外一个给定的子字符串 “结尾” |
| |
| position 表示开始查找的索引,默认为 str.length |
| |
| let str = 'hello' |
| |
| console.log(str.endsWith('llo')) => true |
| |
| let str = "To be, or not to be, that is the question." |
| |
| console.log(str.endsWith('question.')) => true |
| console.log(str.endsWith('to be')) => false |
| console.log(str.endWith('to be',19)) => true |
includes() ( ES6 新增特性 )
| includes(searchString[, position]) |
| |
| 判断原字符串是否包含给定的字符串 |
| |
| position表示开始查找的索引,默认为 0 |
| |
| let str = "caixin" |
| |
| console.log(str.includes("cai")) => true |
indexOf()
| indexOf(searchValue[, fromIndex]) |
| |
| 返回给定的字符串在原字符串的 第一次 出现的索引值 |
| |
| 未找到返回 -1 |
| |
| fromIndex 表示开始查找的索引 |
| |
| console.log('caixin'.indexOf('i')) => 2 |
| |
| 注意: |
| |
| console.log('caixin'.indexOf('')) => 0 |
lastIndexOf()
| lastIndexOf(searchValue[, fromIndex]) |
| |
| 返回给定的字符串在原字符串的 最后一次 出现的索引值 |
| |
| 未找到返回 -1 |
| |
| fromIndex 表示开始查找的索引 |
| |
| let str = "Brave new world" |
| |
| console.log(str.lastIndexOf('new')) => 6 |
search()
| str.search(regexp) |
| |
| 用于检索字符串中指定的子字符串,或检索与正则表达式相匹配的子字符串 |
| |
| 返回 str 中第一个与 regexp 相匹配的子串的起始位置,未找到返回 -1 |
| |
| regexp 是一个正则表达式对象,如果传入了非正则表达式,则会使用 new RegExp(regexp) |
| |
| let str = 'hello' |
| |
| console.log(str.search('/el/')) => 1 |
match()
| str.match(regexp) |
| |
| 用于在字符串内检索指定的值,或找到一个或多个正则表达式的匹配 |
| |
| 它返回指定的值,而不是字符串的位置 |
| |
| let str = "abcdef" |
| |
| console.log(str.match('c')) => "c" |
matchAll()
| str.matchAll(regexp) |
| |
| 返回一个包含所有匹配正则表达式及分组捕获结果的迭代器 |
| |
截取
slice()
| slice(beginSlice[, endSlice]) |
| |
| 第一个参数指定子字符串的开始位置 |
| |
| 第二个参数表示子字符串到哪里结束 |
| |
| 若缺少第二个参数,则将字符串的末尾作为结束位置 |
| |
| 若参数是负值,将参数与字符串长度相加 |
| |
| let str = "hello world" |
| |
| console.log(str.slice(0,3)) => 'hel' |
| |
| console.log(str.slice(3)) => 'lo world' |
| |
| console.log(str.slice(3,-4)) => 'lo w' |
substring()
| substring(indexStart[, indexEnd]) |
| |
| 和 slice() 基本一致 |
| |
| 若传入参数为负数,则把所有负值都转换为 0 |
| |
| 会将较小的数作为起始位置 |
| |
| let str = "hello world" |
| |
| console.log(str.substring(3,-4)) => 'hel' |
split()
| split([separator[, limit]]) |
| |
| 基于指定的分隔符将一个字符串分割成多个字符串,并将结果放在一个数组中 |
| |
| 接收第二个参数,用于指定数组的大小,以便确保返回的数组不会超过既定大小 |
| |
| 可以接收一个正则表达式,有浏览器差异 |
| |
| let colorText = 'red,blue,green,yellow' |
| |
| console.log(colorText.split(',')) => ["red", "blue", "green", "yellow"] |
| |
| console.log(colorText.split(',',2)) => ['red','green'] |
trim()
| 创建一个字符串的副本,删除前置以及后缀的所有空格 |
| |
| let str = " hello word " |
| |
| console.log(str.trim()) => 'hello world' |
trimRight()
trimLeft()
charAt()
| str.charAt(index) |
| |
| 从原字符串中返回指定索引的字符 |
| |
| 如果不写 index,则默认 index 为 0 |
| |
| 访问不到 则 返回 一个 ‘’ 空字符串 |
| |
| let str = "hello" |
| |
| console.log(str.charAt(0)) => 'h' |
replace()
| replace(regexp|substr, newSubStr|function) |
| |
| 返回原字符串以特定规则被替换后的字符串 |
| |
| 当前字符串不变 |
| |
| 第一个参数可以是一个RegExp对象或者字符串 |
| |
| 第二个参数可以是一个字符串或者一个函数 |
| |
| var text = "cat, bat, sat, fat" |
| |
| var result = text.replace(/at/, "ond") |
| console.log(result) => "cond, bat, sat, fat" |
| |
| var result2 = text.replace(/at/g, "ond") |
| console.log(result2) => "cond, bond, sond, fond" |
转换大小写
toLowerCase()
| 返回一个将原字符串转化成小写的字符串 |
| |
| console.log('CAi'.toLowerCase()) => 'cai' |
toUpperCase()
| 将当前字符串转换为大写,返回新字符串 |
| |
| console.log('cAi'.toUpperCase()) => 'CAI' |
字符码点
normalize()
| normalize([form]) |
| |
| 按照指定的一种 Unicode 正规形式将当前字符串正规化 |
charCodeAt()
| charCodeAt(index) |
| |
| 返回指定索引的 UTF-16 代码单元值的数字 |
| |
| 接收一个基于索引的参数,返回给定位置字符的字符编码 |
| |
| 如果索引超出范围,则返回 NaN |
| |
| "123".charCodeAt(0) => 49 |
| "123".charCodeAt(2) => 51 |
| "123".charCodeAt(4) => NaN |
codePointAt()
| codePointAt(index) |
| |
| 与 charCodeAt() 方法返回的结果一致,除了索引超出范围返回的是undefined |
获取索引值
| 方括号表示法 str[index] |
| |
| let str = "123" |
| |
| console.log(str[0]) => 1 |
| |
| console.log(str[3]) => undefined |
ES6 新增
| includes(),startsWith(),endsWith(),repeat() |
字符串的遍历接口 for of
| for(let i of "caix"){ |
| console.log(i) => c,a,i,x |
| } |
at() ( ES7 新增特性 )
| ES7新增,返回字符串给定位置的字符,支持负数, 避免之前 bug |
| |
| let str = "abcABC" |
| |
| str[0] => 'a' |
| str[5] => '5' |
| |
| 如果是索引值是负值呢 ? |
| |
| str[-1] => undefined |
| |
| str.at(-1) => "C" |
| |
| 其实类似的,ES6数组也增加Array.prototype.at方法: |
| |
| let arr = ['A','B','C'] |
| |
| arr.at(-1) => "C" |
模版字符串 ``
| 模板字符串是增强版的字符串,用反引号(`)标识 |
| |
| 它可以当做普通字符串使用,也可以用来定义多行字符串,或者在字符串中嵌入变量 |
| |
| 嵌入变量,需要将变量写在$()中 |
| |
| 大括号中可以放入任意的js表达式,可以进行运算,以及引用对象属性,甚至调用函数 |
| |
| let x = 1 |
| let y = 2 |
| |
| `${x} + ${y} = ${x + y}` => "1 + 2 = 3" |
| |
| let obj = {a:1,b:2} |
| `${obj.a + obj.b}` => "3" |
| |
| function fn(){ |
| return "hello world" |
| } |
| |
| `foo ${fn()} bar` => "foo hello world bar" |
| |
| 补充: |
| |
| String.raw() String 对象的一个静态方法 |
| |
| 一般都是以标签函数的方式调用它,即 |
| |
| String.raw `` |
| |
| 它的用途是获取一个模板字符串的原始字面量值 |
| |
| 简单说就是把所有的反斜杠(\)转义 |
| |
| String.raw `Hi\u000A!`; => "Hi\\u000A!" |
| |
| String.raw `Hi\n${999}!`; => "Hi\\n999!" |
| |
| String.raw`\\`; => "\\\\" |
其它
| codePointAt() 正确处理4个字节存储的字符,返回一个字符的码点 |
| |
| String.fromCodePoint() 从码点返回对应字符,解决之前 bug |
字符编码与字符集
基本概念
| 字符: 是各种文字和符号的总称,包括各国家文字、标点符号、图形符号、数字等 |
| |
| 字符库: 是一个相当于所有可读或者可显示字符的数据库,字库表决定了整个字符集能够展现表示的所有字符的范围。其实就是字符的集合。 |
| |
| 编码字符集: 简称字符集,用一个编码值code point(又称码点)来表示一个字符(即该字符在子库表中的位置),这个值称为字符对应于编码字符集(如:Unicode、ASCII)的序号。 |
| |
| 字符编码: 是编码字符集和实际存储数值之间的转换关系。 |
ASCII
| ASCII 既是字符集,也是字符编码。用一个字节的长度存储字符。 |
Unicode
| Unicode 是一个字符集,为每个符号指定一个编号,即"码点"(code point)。其目标是将全世界所有的字符包含在一个集合里,计算机只要支持这一个字符集,就能显示所有的字符。 |
UTF-32
| UTF-32 是字符编码方式,用固定长度的 4 字节表示一个字符,与 Unicode 字节内容一一对应码点。 |
| |
| 如: |
| |
| U+597D = 0x0000 597D |
| |
| 缺点很明显,浪费空间。 |
| |
| HTML5 标准就明文规定,网页不得编码成 UTF-32。 |
UTF-8
| UTF-8 是一种变长的编码方法,字符长度从 1 个字节到 4 个字节不等。越是常用的字符,字节越短,最前面的 128 个字符,只使用 1 个字节表示,与 ASCII 码完全相同。 |
| |
| 编码范围在0x0000 - 0x007F只占用 1 字节, |
| |
| 而0x010000 - 0x10FFFF要占用 4 字节。 |
| |
| 是最常见的网页编码 |
UTF-16
| UTF-16 编码介于 UTF-32 与 UTF-8 之间,同时结合了定长和变长两种编码方法的特点。编码规则就是,基本平面的字符占用 2 个字节,辅助平面的字符占用 4 个字节。 |
JavaScript 使用的编码方式
| JavaScript 语言采用 Unicode 字符集,但是只支持一种编码方法,就是 UCS-2 |
| |
| UCS-2 只支持 2 字节的字符,4 字节的字符被当成 2 个 2 字节的字符解析。现在已经没有 UCS-2 。 |
ES6 增强对 Unicode 的支持
| ES6 可以自动识别 4 字节的码点 |
| |
| 允许直接用码点表示Unicode字符 |
| |
| ES6 新增了几个专门处理 4 字节码点的函数 |
| |
| ES6 的正则表达式提供了u修饰符,对正则表达式添加 4 字节码点的支持 |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构