JavaScript 基本类型和引用类型

来源:互联网 发布:知乎精华故事 编辑:程序博客网 时间:2024/06/06 18:00

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说明:即是在函数内部修改了参数的值,原始的引用仍保持不变。而且重写的对象是一

个局部变量,在函数执行完毕之后就会被销毁。


原创粉丝点击