首页
ECMAScript中的直接量
ECMAScript中的直接量
版权声明:本文为原创内容,转载请声明出处。
原文地址:http://www.excelib.com/article/262/show

概念

直接量的概念学生在前面内存模型中已经给大家介绍过了,他是指不需要创建对象就可以直接使用的变量,我们这里主要给大家介绍其中最常用的三种:表示字符串string类型、表示数字的number类型和表示true/flaseboolean类型,首先我们来看怎么使用

1
2
3
4
5
6
7
8
9
10
var str = "hello word";
console.log(typeof str);                     //string
var num = 210;
console.log(typeof num);                     //number
var num1 = 325.7;
console.log(typeof num1);                    //number
var flag = false;
console.log(typeof flag);                    //boolean
flag = 376;
console.log(typeof flag);                    //number

通过这个例子我们可以看出,当我们直接将值赋给变量之后ECMAScript就会自动判断其类型,而且当参数值发生变化之后(比如例子中的flag)其类型也会自动跟着发生变化,也就是说ECMAScript是一种弱类型的语言。另外,对于数字类型来说无论是整数还是小数都是number类型。

保存方式

前面我们在内存模型中说过,直接量是直接使用两块内存来保存他们的名值对的,而不像对象类型那样需要三块内存。明白了这一点我们就可以知道,直接量是各自保存各自的值,他们不会相互影响,比如下面的例子

1
2
3
4
var m = 5;
 var n = m;
 m = 7;
 console.log(n);                //5

这里虽然将m赋值给了n,但是只是将m的值赋给了n,当m发生变化的时候n并不是发生变化,这一点和对象类型是不同的,如果是对象类型,赋值的时候只是将对象的地址赋给的新值,当对象中的属性发生变化时两个对象都会发生变化,比如下面的例子

1
2
3
4
var obj = {m:5};
 var newObj = obj;
 obj.m = 7;
 console.log(newObj.m);   //7

这个例子中objnewObj使用的就是同一个对象,所以当obj中的m属性发生变化时newObj中的m属性也会发生变化。

封包与解包

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 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.toString());                                 //true

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

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

1
2
3
4
5
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类型。

实际使用中我们很少有直接使用直接量所对应的包装对象,所以封包功能使用的非常多,但是解包功能很少使用到。

明白了封包和解包的含义,大家肯定想知道不同的直接量所对应的包装对象是什么呢?不同的包装对象都有哪些可以使用的功能呢?学生下一节详细给大家进行介绍。