第七篇 基本包装类型-字符串类型 - String、Number、Boolean

发布时间 2023-03-28 14:21:32作者: caix-1987

基本包装类型

基本包装类型是 特殊的 引用类型

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
     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 字节码点的支持