很多语言中都有Box和Unbox的概念,很多书籍把Box翻译为”装箱操作”,指的是將基本数据类型包装成对象;Unbox和它相反,把对象类型转换为基本类型。
我们知道JavaScript中只有对象才有属性和方法,看下面的代码,你可能会产生一些疑惑:
<script type="text/javascript">
var str = "hello world";
var num = 200;
alert(typeof str);//string
alert(typeof num);//number
alert(str.length);//11
alert(num.toString());//200
</script>
细心的朋友会发现,我们定义两个变量,str变量存放string类型数据,num 变量则存放number类型数据。下面我们竟然可以使用str.length
属性获取字符串的长度,还可以直接使用num.toString()
这种形式將数值转换为字符串。
为什么可以这样调用呢?不是说只有对象才有属性和方法吗?
上一节中提到JS提供一些内置对象模版,每种基本类型都有相应的对象模版与之对应,例如string->String,number->Number等等。事实上,当我们使用基本类型调用属性或方法时,JS引擎会自动將基本类型装箱成对象模版对应的对象。
str.length
这段代码JS引擎会自动做类似与下面的处理:
new String(str).length
为了证明这一点,笔者写了下面一段代码:
<script type="text/javascript">
String.prototype.getLen = function()
{
return this.length;
}
var str = "hello world";
alert(str.getLen());
</script>
为String对象模版增加一个自定义的成员方法getLen(),可以看到我们一样可以使用str.getLen()
形式调用。
所以出于提高性能考虑,请尽量不要写下面类似的代码:
<script type="text/javascript">
var str = "hello world";
//for循环中使用str.length
for(i=0;i<str.length;i++)
{
//...
}
</script>
拆箱操作(Unbox)就更简单了,分为自动拆箱和手动拆箱两种,例如:
<script type="text/javascript">
var strObj = new String("hello world");
alert(typeof strObj);//object
alert(typeof (strObj + ""));//string
alert(typeof strObj.valueOf());//sring
</script>
当对象类型和基本类型数据进行运算时会自动拆箱,我们还可以手动调用对象的valueOf()方法进行拆箱。