String 类型用于表示由零或多个16位 Unicode 字符组成的字符序列,即字符串 。
存储结构
由于计算机只能处理数字,如果要处理文本,就必须先把文本转换为数字才能处理。在计算机中,1个字节(byte)由 8个比特(bit)组成,所以 1 个字节能表示的最大整数就是 255,如果想表示更大整数,就必须用更多的字节,比如 2 个字节可以表示的最大整数为 65535 。最早,只有127个字符被编码到计算机里,也就是大小写英文字母、数字和一些符号,这个编码表被称为ASCII编码,比如大写字母A的编码是65,小写字母z的编码是122。 但如果要表示中文字符,显然一个字节是不够的,至少需要两个字节。所以,中国制定了GB2312编码,用来表示中文字符。基于同样的原因,各个国家都制定了自己的编码规则。这样就会出现一个问题,即在多语言混合的文本中,不同的编码会出现冲突,导致乱码出现。 为了解决这个问题,Unicode 编码应运而生,它把所有的语言都统一到一套编码中,采用2个字节表示一个字符,即最多可以表示65535个字符,这样基本上可以覆盖世界上常用的文字,如果要表示更多的文字,也可以采用4个字节进行编码,这是一种通用的编码规范。 因此,JavaScript中的字符也采用Unicode来编码,也就是说,JavaScript中的英文字符和中文字符都会占用2个字节的空间大小,这种多字节字符,通常被称为宽字符。
基本包装类型
在JavaScript中,字符串是基本数据类型,本身不存任何操作方法。为了方便的对字符串进行操作,ECMAScript提供了一个基本包装类型:String()
对象。它是一种特殊的引用类型,JS引擎每当读取一个字符串的时候,就会在内部创建一个对应的String()
对象,该对象提供了很多操作字符的方法,这就是为什么能对字符串调用方法的原因。
var 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
对象 。
常用操作方法
作为字符串的基本包装类型,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) // ‘’