1.基本类型值指的是简单的数据段。常见的有5种基本数据类型:Undefined、
Null、Boolean、Number和String。这5种基本数据类型是按值访问的,因为可
以操作保存在变量中的实际的值。
2.引用类型值指的是那些可能由多个值构成的对象。JavaScript不允许直接访
问内存中的位置,即不能直接操作对象的内存空间。在操作对象时,实际上是
在操作对象的引用而不是实际的对象。所以,引用类型的值是按引用访问的。
3.动态的属性:
对于引用类型的值,我们可以为其添加属性和方法,也可以修改或删除其属性
和方法。参见如下的例1:
例1:
var person=new Object();
person.name="Kim";//为对象添加name的属性
alert(person.name);//此时成功输出person.name的值为Kim
person.name="Frank";
alert(person.name);//此时输出为Frank,说明person.name的值被修改了
但我们不能给基本类型的值添加属性,以例2来说明:
例2: var man="Tom";
alert(man);//输出为Tom,没问题
man.age="21";
alert(man.age);//此时输出值为undefined
综合以上的例1和例2,说明只能给引用类型值动态的添加属性。
4.复制变量值:
如果从一个变量向另一个变量复制基本类型值,会在变量对象上创建一个新值,然后
把该值复制到为新变量分配的位置上,此时两个变量分别存储着相同的值,但互不影
响。如例3:
例3:
var num1 = 1;
var num2 = num1;
alert("num1="+num1+"\n"+"num2="+num2);//此时输出的两个变量值都为1
num1=2;
alert("num1="+num1+"\n"+"num2="+num2);//此时num1=2,num2=1
当从一个变量向另一个变量复制引用类型的值时,此时复制的是一个指针,指向存储在
堆中的一个对象。当复制操作结束后,两个变量实际上引用的是同一个对象,若改变其中
的一个变量,就会影响另一个变量。如例4所示:
例4:
var person=new Object();
var man=person;
person.name="Kim";//为对象添加name的属性
alert(man.name);//输出Kim
man.name="John";
alert(person.name);//输出John
5.传递参数:
ECMAScript中所有函数的参数都是按值传递的。也就是说,把函数外部的值复制给函数
内部的参数,就和把值从一个变量复制到另一个变量一样。基本类型值的传递如同基本类
型变量的复制;而引用类型值的传递就如同引用类型变量的复制。访问变量有两种方式:
按值方式和按引用的方式,而参数只能按值传递。
当传递的是基本类型的值时,参见例5:
例5:
function sum(num){
num+=10;
return num;
}
var count=10;
var res=sum(count);
alert(count); //输出值为10,count是基础类型,当传递参数时是复制变量的值给参数
alert(res); //输出值为20,num只是和count的值相同,二者互不影响
例5说明基本类型的值在传递参数的时候是按值传递的,如果是按引用传递的
话,count的值应该是20。
当传递的是引用类型的值时,参见如下例6:
例6:
function setName(obj){
obj.name="Tim";
obj={};
obj.name="John";
}
var nm={}; //定义nm为一个空对象
setName(nm); //调用函数setName,并为其传递参数,此时的参数是一个对象
alert(nm.name); //输出结果为Tim
对于例6,如果传递了参数nm时,假设nm的传参方式是按引用传递的,我们可做如下分析:
代码7: function setName(obj){ //当nm是按引用传递时,此时的obj可替换为nm
obj.name="Tim"; //这行代码可以替换为 nm.name="Tim"
obj={}; //将nm转化为空对象
obj.name="John"; //修改num的name属性值为"John"
}
var nm={};
setName(nm);
alert(nm.name); //此时的输出值应为John,但结果并不是!
由代码7的分析可知:引用类型的传参不是按引用传递。
所以引用类型传参只能是按值传递。
那么,对于代码7我们应该这样来理解:
代码8:
function setName(obj){ //当nm是按值传递时,此时的obj和nm的指针相同
均指向内存中的同一个对象
obj.name="Tim"; //nm.name="Tim",即是内存中的对象的name属性值
obj={}; //此时将obj的指针进行改变,指向的是一个空对象
但nm的指针指向并未改变!
obj.name="John"; //将obj指向的对象的对象的name属性值修改为"John"
}
var nm={};
setName(nm);
alert(nm.name); //此时输出的是nm所指向的对象的name属性,仍为"Tim"
例8说明:即是在函数内部修改了参数的值,原始的引用仍保持不变。而且重写的对象是一
个局部变量,在函数执行完毕之后就会被销毁。