3.4.6 String类型
String类型用于表示由零个或者多个16为Unicode字符组成的字符序列。字符串可以由双引号(“)或者单引号(‘)表示,因此下面两种字符串的写法都是有效的。
var firstName = "Nicholas";
var lastName = 'Zakas';
与PHP中的双引号和单引号会影响对象字符串的解析方式不同,ECMAScript中的这两种语法形式没有什么区别。用双引号的字符串和单引号的字符串完全不同。不过,这双引号开头的字符串也必须以双引号结尾。例如,下面这种字符串的表示方法会导致错误:
var firstName = 'Nicholas"; // 语法错误
1 字符字面量
String数据类型包含一些特殊字符字面量,也叫转义序列,用于表示非打印字符,或者有其它用途的字符,这些字符字面量如下表所示:
字面量 | 含义 |
---|---|
\n | 换行 |
\t | 制表 |
\b | 空格 |
\r | 回车 |
\ | 斜杠 |
\’ | 单引号 |
\” | 双引号 |
\xnn | 以十六进制代码表示一个字符(其中n为0-F),例如,\X41 |
\unnnn | 以十六进制代码nnnn表示一个Unicode字符(其中n为0-F)。例如,\u03a3表示希腊字符”Σ” |
这些字符字面量可以出现在字符串中的任意位置,而且也将被作为一个字符来解析,如下面的例子所示:
var text = "This is the letter sigma: \u03a3";
这个例子中变量text有28个字符,其中6个字符长的转义序列表示一个字符。
任何字符串的长度都可以通过访问其length属性取得,例如:
alert(text.length); // 输出28
这个属性返回的是字符数包括16为字符数目。如果字符串中包含双字节字符,那么length属性可能不会精确的返回字符串中的字符数目。
2 字符串的特点
ECMAScript中的字符串是不可变的,也就是说,字符串一旦建立,它们的值就不能改变。要改变某个变量保存的字符串,首先要销毁原来的字符串,然后再用另一个包含新值的字符串填充该变量,例如:
var lang = "Java";
lang = lang + "Script";
以上示例中的变量lang开始时包含字符串”Java”。而第二行代码把lang的值重”Java”重新与”Script”的组合,即”JavaScript”。实现这个这个这个操作的过程如下:首先创建能够容纳10个字符的新字符串,然后在这个字符串中填充”Java”和”Script”,最后一步是销毁原来的字符串”Java”和字符串”Script”,因为这两个字符串已经没有用了。这个过程是在后台发生的,而这也是某些就得浏览器中拼接字符串很慢的原因所在,但是这些浏览器在后期的版本中已经解决了这个问题。
3 转换为字符串
要把一个值转换为一个字符串由两种方式。第一种是使用几乎每个值都有的toString()方法。这个方法唯一要使用的就是返回相应的字符串表现。来看下面的例子:
var age = 11;
var ageAsString = age.toString(); // 字符串"11"
var found = true;
var foundAsString = found.toStrng(); // 字符串"true"
数值、布尔值、对象和字符串(没错,每个字符串都有一个toString()方法,该方法返回一个字符串的副本)都有toString()方法。但是null和undefined值没有这个方法。
多数情况下,调用toString()方法不必传递参数。但是,在调用数值的toString()方法时候,可以传递一个参数,输出数值的基数。默认情况下,toString()方法以十进制格式返回数值字符串表示。而通过传递基数,toString()可以输出二进制。八进制、十六进制,乃至任意进制的有效进制格式表示的字符串。下面给出几个例子:
var num = 10;
alert(num.toString()); // "10"
alert(num.toString(2)); // "1010"
alert(num.toString(8)); // "12"
alert(num.toString(10)); // "10"
alert(num.toString(16)); // "a"
通过这个例子可以看出,通过指定基数,toString()方法会改变输出的值。而数值10根据基数的不同,可以输出时候被转换为不停数值格式。注意,默认的(没有参数的)输出值与指定基数的10是输出值相同。
在不知道转换的值是不是null或者undefined的情况下,还可以使用转型函数String(),这个函数能够将任何类型的值转换为字符串。String()函数遵循下列转换规则:
- 如果值由toString()方法,则调用该方法并返回相应的结果;
- 如果值是null,则返回null;
- 如果值是undefined,则返回”undefined”;
下面再看几个例子:
var value1 = 10;
var value2 = true;
var value3 = null;
var value4;
alert(String(value1)); // "10"
alert(String(value2)); // "true"
alert(String(value3)); // "null"
alert(String(value4)); // "undefined"
这里先后转换了4个值:数值、布尔值、null和undefined。数值和布尔值的转换结果与调用toString()方法得到的结果相同。因为null和undefined没有toString()方法,所以String()函数就返回了这两个值的字面量。
要把某个值转换为字符串,可以使用加号把它与一个字符串(“”)加在一起。
3.4.7 Object类型
ECMAScript中的对象其实就是一组数据和功能的集合。对象可以通过执行new操作符跟要创建的对象类型的名称来创建。而创建的Object类型的实例并为其添加属性和(或)方法,就可以创建自定义对象,如下所示:
var o = new Object();
这个语法与Java中创建对象的语法类似;但是在ECMAScript中,如果不给构造函数传递参数,完全可以省略那对圆括号(但是不推荐这样的做法)。
var o = new Object; // 有效,但是不推荐
仅仅创建Object的实例并没有什么用处,但是关键是要理解一个重要的思想:即在ECMAScript中,(就像Java中的java.lang.Object对象一样)Object类型是所有他的实例的基础。换句换说,Object类型具有的任何属性和方法也存在更具体的对象之中。
Object的每个实例都具有下列属性和方法。
- constructor:保存着用于创建当前对象的函数。对于前面的例子而言,构造函数(constructor)就是Object()。
- hasOwnProperty(propertyName):用于检查给定的属性在当前对象实例中(而不是实例的原型中)是否存在。其中,作为参数的属性名(propertyName)必须以字符串形式指定(例如:o.hasOwnProperty(“name”));
- isPrototypeOf(object):用于检查传入的对象是否是传入对象的原型。
- propertyIsEnumerable(propertyName):同于检查给定的属性是否能够使用for-in语句来枚举。与hasOwnProperty()方法一样,作为参数的属性名必须以字符串的形式。
- toLocaleString():返回对象的字符串形式,该字符串与执行环境的地区对应。
- toString():返回对象的字符串表示。
- valueOf():返回对象的字符串。数值或者布尔值表示。通常与toString()方法的返回值相同。
由于在ECMAScript中的Object是所有对象的基础,因此对所有对象都具有这些基本的属性和方法。
从技术角度讲,ECM-262中的对象的行为不一定适用于JavaScript中的其他对象。浏览器环境中的对象,比如BOM和DOM中的对象,都属于宿主对象,因为它们是由宿主实现和提供的。ECMA-262不负责宿主对象,因此宿主对象可能会也可能不会继承Object。