[TOC] # **String:字符串类型** String类型用于表示由零或多个16位Unicode字符组成的字符序列,即字符串 。 <br> ## **1、存储结构** &emsp;&emsp;由于计算机只能处理数字,如果要处理文本,就必须先把文本转换为数字才能处理。在计算机中,1个字节(byte)由 8个比特(bit)组成,所以 1 个字节能表示的最大整数就是 255,如果想表示更大整数,就必须用更多的字节,比如 2 个字节可以表示的最大整数为 65535 。最早,只有 127 个字符被编码到计算机里,也就是大小写英文字母、数字和一些符号,这个编码表被称为 ASCII编码,比如大写字母 A 的编码是 65,小写字母 z 的编码是122。 &emsp;&emsp;但如果要表示中文字符,显然一个字节是不够的,至少需要两个字节。所以,中国制定了 GB2312 编码,用来表示中文字符。基于同样的原因,各个国家都制定了自己的编码规则 。这样就会出现一个问题,即在多语言混合的文本中,不同的编码会出现冲突,导致乱码出现 。 &emsp;&emsp;为了解决这个问题,Unicode 编码应运而生,它把所有的语言都统一到一套编码中,采用 2 个字节表示一个字符,即最多可以表示 65535 个字符,这样基本上可以覆盖世界上常用的文字,如果要表示更多的文字,也可以采用 4 个字节进行编码,这是一种通用的编码规范 。 &emsp;&emsp;因此,JavaScript 中的字符也采用 Unicode 来编码 ,也就是说,JavaScript 中的英文字符和中文字符都会占用 2 个字节的空间大小 ,这种多字节字符,通常被称为宽字符。 <br> ## **2、基本包装类型** &emsp;&emsp;在 JavaScript 中,字符串是基本数据类型,本身不存任何操作方法 。为了方便的对字符串进行操作,ECMAScript 提供了一个基本包装类型:String 对象 。它是一种特殊的引用类型,JS引擎每当读取一个字符串的时候,就会在内部创建一个对应的 String 对象,该对象提供了很多操作字符的方法,这就是为什么能对字符串调用方法的原因 。 ``` 12var name ='JavaScript'; var value = name.substr(2,1); ``` &emsp;&emsp;当第二行代码访问变量 str 时,访问过程处于一种读取模式,也就是要从内存中读取这个字符串的值。而在读取模式中访问字符串时,引擎内部会自动完成下列处理: * 创建 String 类型的一个实例 * 在实例上调用指定的方法 * 销毁这个实例 &emsp;&emsp;用伪代码形象的模拟以上三个步骤: ``` var obj =new String('JavaScript'); var value = obj.substr(2,1); name =null; ``` &emsp;&emsp;可以看出,基本包装类型是一种特殊的引用类型。它和普通引用类型有一个很重要的区别,就是对象的生存期不同 。使用 new 操作符创建的引用类型的实例,在执行流离开当前作用域之前都一直保存在内存中。而自动创建的基本包装类型的对象,则只存在于一行代码的执行瞬间,然后立即被销毁。在 JavaScript 中,类似的基本包装类型还有 Number、Boolean 对象 。 <br> ## **3、常用操作方法** 作为字符串的基本包装类型,String 对象提供了以下几类方法,用以操作字符串: * 字符操作:charAt,charCodeAt,fromCharCode * 字符串提取:substr,substring ,slice * 位置索引:indexOf ,lastIndexOf * 大小写转换:toLowerCase,toUpperCase * 模式匹配:match,search,replace,split * 其他操作:concat,trim,localeCompare &emsp;&emsp;charCodeAt 的作用是获取字符的 Unicode 编码,俗称 “Unicode 码点”。fromCharCode 是 String 对象上的静态方法,作用是根据 Unicode 编码返回对应的字符。 ``` var a ='a'; // 获取Unicode编码 var code = a.charCodeAt(0); // 97// 根据Unicode编码获取字符 String.fromCharCode(code); // a ``` &emsp;&emsp;通过 charCodeAt 获取字符的 Unicode 编码,然后再把这个编码转化成二进制,就可以得到该字符的二进制表示。 ``` var a ='a'; var code = a.charCodeAt(0);// 97 code.toString(2);// 1100001 ``` &emsp;&emsp;对于字符串的提取操作,有三个相类似的方法,分别如下: ``` substr(start [, length]) substring(start [, end]) slice(start [, end]) ``` &emsp;&emsp;从定义上看,substring 和 slice 是同类的,参数都是字符串的某个 start 位置到某个 end 位置(但 end 位置的字符不包括在结果中);而 substr 则是字符串的某个 start 位置起,数 length 个长度的字符才结束。二者的共性是:从 start 开始,如果没有第 2 个参数,都是直到字符串末尾。 &emsp;&emsp;substring 和 slice 的区别则是:slice 可以接受 “负数”,表示从字符串尾部开始计数; 而 substring 则把负数或其它无效的数当作 0。 ``` 'hello world!'.slice(-6, -1)// 'world' 'hello world!'.substring("abc", 5)// 'hello' ``` &emsp;&emsp;substr 的 start 也可接受负数,也表示从字符串尾部计数,这点和 slice 相同;但 substr 的 length 则不能小于 1,否则返回空字符串。   ``` 'hello world!'.substr(-6, 5)// 'world' 'hello world!'.substr(0, -1)// ''