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