JavaScript高级程序设计第5章读书笔记(14)
基本包装类型
为了便于操作基本类型值,ECMAScript还提供了3个特殊的引用类型: Boolean
、Number
和String
。实际上,每当读取一个基本类型值的时候,后台就会创建一个对应的基本包装类型的对象,从而让我们能够调用一些方法来操作这些数据。比如:
1 2 3 |
var s1 = "some text"; var s2 = s1.substring(2); |
这个例子中,变量s1包含一个字符串,字符串当然是基本类型值。而下一行调用了s1的substring()方法,并将返回的结果保存在了s2中。我们知道,基本类型值不是对象,因此从逻辑上讲它们不应该有方法。但实际上,为了让我们实现这种直观的操作,后台已经自动完成了一系列的处理。当第二行代码访问s1时,访问过程处于一种读取模式,也就是要从内存中读取这个字符串的值。而在读取模式中访问字符串时,后台都会自动完成下列处理。
- 创建String类型的一个实例
- 在实例上调用指定的方法
- 销毁这个实例
可以将以上3个步骤想象成是执行了下列ECMAScript代码。
1 2 3 4 |
var s1 = new String("some text"); var s2 = s1.substring(2); s1 = null; |
上面3个步骤也分别适用于Boolean和Number类型对应的布尔值和数字值。引用类型与基本包装类型的主要区别就是对象的生存期。使用new操作符创建的引用类型的实例,在执行流离开当前作用域之前都一直保存在内存中。而自动创建的基本包装类型的对象,则只存在于一行代码的执行瞬间,然后立即被销毁。这意味着,我们不能在运行时为基本类型值添加属性和方法。比如:
1 2 3 4 |
var s1 = "some text"; s1.color = "red"; alert(s1.color); // undefined |
上面的例子中,第二行代码试图为字符串s1添加一个color属性。但是,当第三行代码再次访问s1时,其color属性已经不见了。因为,第二行代码创建的String对象在执行第三行代码时已经被销毁了。第三行代码又会自动创建自己的String对象,而该对象是没有color属性的。
虽然,我们可以显式地调用Boolean、Number和String来创建基本包装类型的对象。但是,不建议这么做,这样会让人难以分清自己是在处理基本类型还是引用类型的值。对基本包装类型的实例调用typeof会返回”object”,而且所有基本包装类型的对象都会转换为布尔值。
Object构造函数也会像工厂方法一样,根据传入值的类型返回相应基本包装类型的实例。比如:
1 2 3 |
var obj = new Object("some text"); alert(obj instanceof String); // true |
把字符串传给Object构造函数,就会创建String的实例;而传入数值参数会得到Number的实例,传入布尔值参数就会得到Boolean的实例。
要注意的是,使用new调用基本包装类型的构造函数,与直接调用同名的转型函数是不一样的。比如:
1 2 3 4 5 6 7 |
var value = "25"; var number = Number(value); // 转型函数 alert(typeof number); // "number" var obj = new Number(value); // 构造函数 alert(typeof obj); // "object" |
Boolean类型
Boolean类型是与布尔值对应的引用类型。要创建Boolean对象,可以用如下方法:
1 2 |
var booleanOjbect = new Boolean(true); |
Boolean类型的实例重写了valueOf()方法,返回基本类型值true或false;重写了toString()方法,返回字符串”true”和”false”。但Boolean对象在ECMAScript中用处不大,因为容易造成误解。比如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
var falseObject = new Boolean(false); var result = falseObject && true; // 布尔表达式中的所有对象都会被转换为true alert(result); // true var falseValue = false; result = falseValue && true; alert(result); // false alert(typeof falseObject); // "object" alert(typeof falseValue); // "boolean" alert(falseObject instanceof Boolean); // true alert(falseValue instanceof Boolean); // false |
基本类型与引用类型的布尔值还有两个区别。首先,typeof操作符对基本类型返回”boolean”,而对引用类型返回”object”。其次,由于Boolean对象是Boolean类型的实例,所以使用instanceof操作符测试Boolean对象会返回true,而测试基本类型的布尔值则返回false。
建议永远不要使用Boolean对象。