看透JavaScript:原理、方法与实践
上QQ阅读APP看书,第一时间看更新

6.2 直接量的封包与解包

直接量是单个值,并不是对象,当然也就没有属性。但是在ES中,我们可以使用直接量来调用属性方法,例如下面的例子。

    function log(msg){
        console.log(msg);
    }


    var s ="hello";
    log(s.toUpperCase());                                     //HELLO
    log(s.substr(3, s.length));                               //lo


    var n = 325.764;
    log(n.toPrecision(5));                                   //325.76
    log(n.toExponential(5));                                 //3.25764e+2


    n = 7596389;
    log(n.toLocaleString());                                 //7,596,389
    log(n.toLocaleString("zh-Hans-CN-u-nu-hanidec"));        //七,五九六,三八九


    var b = true;
    log(b ===“true”);                                       //false
    log(b.toString() ===“true”);                            //true
    log(b.toString() === true);                             //false

这个例子中,string类型的变量s调用了toUpperCase、substr和length属性,分别用于将s的值变为大写、截取s的一部分及获取s的长度;number类型的变量n调用了toPrecision、toExponential和toLocaleString方法,分别用于设置n的精度、将n转换为科学计数法,以及将n转换为本地数组表达格式;boolean类型的b属性调用了toString方法,用于将boolean转换为string类型。

既然直接量只是一个值而不是对象,那么它怎么可以调用属性方法呢?原来ES有一种叫作自动封包/解包的功能。封包/解包对于熟悉Java的读者来说一定不会陌生(在Java中也称装箱/拆箱,它们的含义都一样),其作用是在程序执行过程中按照实际需要自动在直接量和其所对应的对象类型之间进行转化。将直接量转换为对应的对象进行处理叫作封包,反过来,将对象转换为直接量叫作解包。封包和解包都是JS引擎自动完成的,而且只是为了完成程序的执行而进行的暂时转换,并不会实际修改变量的类型。有了封包/解包我们就不需要考虑什么时候使用直接量什么时候使用对象了,而且也不需要担心变量类型会发生变化。上面的例子就使用了封包功能,下面我们再来看一个使用到解包功能的例子。

    var m = new Number(5);
    var n = m+2;                      //m会自动解包为直接量后再计算
    console.log(n);                   //7
    console.log(typeof  m);          //object
    console.log(typeof  n);          //number

这个例子中,定义了对象类型的m变量,当对其进行加法计算时m会自动解包为直接量再进行计算,但是计算之后m的类型并不会变化,还是object类型。

实际使用中我们很少直接使用直接量所对应的包装对象,所以封包功能使用得非常多,但是解包功能相对使用得就比较少了。