基本类型和引用类型的值
ECMAScript变量可能包含两种不同的数据类型的值:基本类型和引用类型值。
基本类型值指得是简单的数据段,而引用类型值指那些可能由多个值构成的对象。
在将一个值赋给变量的时,解析器必须确定这个值是基本类型值还是引用类型值。其中5种基本数据类型:Undefined、Null、Boolean、Number、String。这5种基本数据类型是按值访问的,因此可以操作保存在变量中的实际的值。
引用类型的值是保存在内存中的对象。与其他语言不同,javascript不允许直接访问内存中的位置,也就是说不能直接操作对象内存空间。在操作对象的时,实际上是在操作对象的引用而不是实际的对象,为此,引用类型的值是按引用访问的。
1.动态的属性
定义基本类型值和引用类型值的方式是类似的:创建一个变量并为该变量赋值。但是,当这个值保存到变量中以后,对不同类型值可以执行的操作则大相径庭。对于引用类型的值,我们可以为其添加属性和方法,也可以改变和删除其属性和方法。请看下面例子:
var person=new Object(); person.name="Nicholas"; alert(person.name);//Nicholas
以上代码创建了一个对象并将其保存在了变量person中。然后,我们为该对象添加了一个名为name的属性,并将字符串值"Nicholas“赋给了这个属性。紧接着,又通过alert()函数访问可这个新属性。如果对象不被销毁或这个属性不被删除,则这个属性将一直存在。
但是,我们不能给基本类型的值添加属性,尽管这样不会导致任何错误。例如:
var name=”Nicholas"; name.age="27"; alert(name.age);//undefined
这个例子中,我们为字符串name定义了一个名为age的属性,并为该属性赋值27.但在下一行访问这个属性时,发现该属性不见了。这说明只能给引用类型值动态地添加属性,以便将来使用。
2.复制变量值
除了保存的方式不同之外,从另一个变量像另一个变量复制基本类型值和引用类型值时,也存在不同。如果从一个变量向另一个变量复制基本类型的值,会在变量对象上创建一个新值,然后把该值复制到为新变量分配的位置上。
当一个变量向另一个变量复制引用类型的值时,同样也会将存储在变量对象中的值复制一份放到为新变量分配的空间中。不同的是这个值的副本实际上是一个指针,而这个指针指向存储在堆中的一个对象。复制操作结束后,两个变量实际上将引用同一个对象。因此,改变其中一个变量,就会影响另一个变量,如下面例子所示:
var obj1=new Object(); var obj2=obj1; obj11.name="Nicholas"; alert(obj2.name);//Nicholas
3.传递参数
ECMAScript中所有的函数参数都是按值传递的。也就是说,把函数外部的值复制给函数内部的参数,就和把值从一个变量复制到另一个变量一样。基本类型值的传递如同基本类型变量复制一样,而引用类型值的传递,则如同引用类型变量的复制一样。有不少开发人员在这一点上可能会感到困惑,因为访问变量有按值和按引用两种方式,而参数只能按值传递。
在参数传递基本类型的值时,被传递的值会被复制给另一个局部变量(即命名参数,或者用ECMAScript的概念来说,就是arguments对象中的一个元素)。在向参数传递引用类型的值时,会把这个值在内存中的地址复制给一个局部变量,因此这个局部变量的变化会反映在函数的外部。请看下面这个例子:
function addTen(num){ num+=10; return num; } var count=20; var result=addTen(count); alert(count);//20 alert(count);//30
4.检测类型
要检测一变量是不是基本数据类型,typeof操作符是最佳的工具。说的具体一点typeof操作符是确定一个变量是字符串、数值、布尔值、还是undefined的最佳工具。如果变量的值是一个对象或null,则typeof操作符会像下面例子所示的那样返回"object“。
var s="Nicholas"; var b=true; var i=11; var u; var n=null; var o=new Object(); alert(typeof s);//string alert(typeof b);//boolean alert(typeof i);//number alert(typeof u);//undefined alert(typeof n);//object alert(typeof o);//object
虽然在检测基本数据类型时typeof是非常得力的助手,但在检测引用类型的值时,这个操作符的用处不大。通常,我们并不是想知道某个值是对象,而是想知道它是什么类型的对象。为此,ECMAScript提供了instanceof操作符,其语法如下所示:
result=variable instanceof constructor
如果变量是给定的引用类型的实例,那么instanceof操作符就会返回true,请看下面的例子:
alert(person instanceof Object);//