为了便于操作基本类型值,ECMAScript还提供了3个特殊的引用类型:Boolean,Number,String.
实际上,每当读取一个基本类型值的时候,后台应付创建一个对应的基本包装类型的对象,从而让我们能够调用一些方法来操作这些数据.
var s1="some text"; var s2=s1.substring(2); console.log(s2);//me text
这个例子中s1包含了一个字符串,字符串是基本类型值.第二行调用了s1的subsstring()方法,并将返回的结果保存在了s2中.
当第二行代码访问s1时,,访问过程处于一种读取模式,也就是要从内存中读取这个字符串的值.而在读取模式中访问字符串时,后台会自动完成下列处理.
(1)创建String类型的一个实例;
(2)在实例上调用指定的方法;
(3)销毁这个实例.
可以将以上三个步骤想象成是执行了下列代码:
var s1=new String("some text"); var s2=s1.substring(2); s1=null; console.log(s2);//me text
经过此番处理,基本的字符串值就变得跟对象一样了.而且上面三个步骤也分别适用于Boolean和Number类型对应的布尔值和数字值.
引用类型与基本包装类型的主要区别就是对象的生存期.
使用new操作符创建的引用类型的实例,在执行流离开当前作用域之前都一起保存在内存中.而自动创建的基本包装类型的对象,则只存在于一行代码的执行瞬间,然后立即被销毁.这意味着我们不能在运行时为基本类型添加属性和方法.
var s1="some text"; s1.color="red"; console.log(s1.color);//undefined
问题的原因就是第二行创建的String对象在执行第三行代码时已经被销毁了.第三行代码又创建自己的String对象,而该对象没有color属性.
对基本包装类型的实例调用typeof会返回"object",而且所有基本包装类型的对象都会被转换为布尔值true.
Object构造函数也会像工厂方法一样,根据传入值的类型返回相应基本包装类型的实例.
var obj=new Object("some text"); console.log(obj instanceof String);//true
把字符串传给Object构造函数,就会创建String的实例,而传入数值参数会得到Number的实例,传入布尔值参数就会得到Boolean的实例.
要注意的是,使用new调用基本包装类型的构造函数,与直接调用同名的转型函数是不一样的.
var value="25"; var number=Number(value);//转型函数 console.log(typeof number);//number var obj=new Number(value);//构造函数 console.log(typeof obj);//object
在这个例子中,变量number中保存的是基本类型的值25,而变量obj中保存的是Number的实例.
5.6.1 Boolean类型
Boolean类型是与布尔值对应的引用类型.要创建Boolean对象,可以像下面这样调用Boolean构造函数并传入true或false值.
var booleanObject=new Boolean(true);
Boolean类型的实例重写了valueOf()方法,返回基本类型值true或false;重写了toString()方法,返回字符串"true”和"false".可是,Boolean对象在ECMAScript中的用处不大,因为它经常会造成人们的误解.
其中最常见的问题是在布尔表达式中使用Boolean对象.
var falseObject=new Boolean(false); var result=falseObject&&true; console.log(result);//true var falseValue=false; result=falseValue&&true; console.log(result);//false
在这个例子中,使用false值创建了一个Boolean对象.然后将这个对象与基本类型值true构造了逻辑与表达式.示例中这行代码是对falseObject而不是它的值(false)进行求值.布尔表达式中所有对象都会被转换成true,因此falseObject对象在布尔表达式中代表的是true.
基本类型与引用类型的布尔值还有两个区别:首先,typeof操作对基本类型返回”boolean”,而对引用类型返回”object”.其次,由于 Boolean对象是Boolean类型的实例,所以使用instanceof操作符测试Boolean对象会返回true,而测试基本类型的布尔值则返回false.
console.log(typeof falseObject);//object console.log(typeof falseValue);//boolean console.log(falseObject instanceof Boolean);//true console.log(falseValue instanceof Boolean);//false
5.6.2 Number类型
Number是与数字值对应的引用类型.要创建Number对象,可以在调用Number构造函数时向其中传递相应的数值.
var numberObject=new Number(10); console.log(typeof numberObject);//object
与Boolean类型一样,Number类型也重写了valueOf(),toLocaleString()和toString()方法.
重写后的valueOf()方法返回对象表壳的基本类型的数值,另外两个方法则返回字符串形式的数值.
可以为toString()方法传递一个表示基数的参数,告诉它返回几进制数值的字符串形式.
var num=10; console.log(num.toString());//10 console.log(num.toString(2));//1010 console.log(num.toString(8));//12 console.log(num.toString(10));//10 console.log(num.toString(16));//a
除了继承的方法之外,Number类型还提供了一些用于将数值格式化为字符串的方法.
其中,toFixed()方法会按照指定的小数位返回数值的字符串表示.
var num=10;
console.log(num.toFixed(2));//10.00
这里给toFixed()方法传入了数值2,意思是显示几位小数.以0填补了必要的小数位.
如果数值本身包含的小数位比指定的还多,那么接近指定的最大小数位的值就会舍入.
var num=10.007; console.log(num.toFixed(2));//10.01