在JavaScript中,变量可能包含两种数据类型的值:基本类型值和引用类型值。
基本类型值:Undefined,Nukk,Boolean,Number,String (访问时按值访问)
引用类型值:Object(访问时按引用访问)
二者有以下不同
1.动态的属性
二者的定义方式相同:创建变量赋值
但是基本类型值的变量不能为其创建属性,引用类型的变量可以创建属性。
var person = new Object();
persion.name = "Daisy";
person.age = 20;
console.log(person.name); //“Daisy”
2. 变量值复制
基本类型的变量进行变量复制的实质是重新创建一个新值,然后为其赋值。这两个变量是独立的,没有关系,修改一个变量的值并不会修改另一个变量的值。
引用类型的变量进行变量赋值的实质是将原变量对象的值复制一份放到为新变量分配的空间中。这个值的副本实际上是一个指针,这个指针指向存储在堆中的一个对象。这两个变量实际上将引用同一个对象,修改一个变量的值另一个变量的值同时会变化。
var obj1 = new Object();
var obj2 = obj1;
obj1.name = "Pengju";
console.log(obj2.name); //"Pengju"
3.传递参数
在JavaScript中,函数参数全部是按照值传递的,不管是基本类型还是引用类型。
例1:参数为基本类型的值
//num是函数addO的局部变量,修改num的值并不会修改count的,这个与基本变量的复制一样
function addO(num){
num++;
return num;
}
var count = 10;
var result = addO(count) ;
console.log(count); //count = 10
console.log(result); //result = 11
例2:参数为引用类型的值
funciton setAge(obj){
obj.age = 22;
}
var person = new Object();
person.age = 20;
setAge(person);
console.log(person.age); //22
乍一看,这似乎是引用传递,其实不是,如果你理解了前面的引用类型的值的复制将会对这一点不会很迷惑。
obj是函数setAge的一个局部变量,在调用这个函数时,将person复制给了obj。他们在内存占用同一个内存空间,所以obj的变化会反应在person上。
为了证明引用类型的值也是按照值传递的,在看下面的例子:
function setAge(obj){
obj.age = 22;
obj = new Object; //重新为obj定义了一个对象
obj.age = 24;
}
var person = new Object();
person.age = 20;
setAge(person);
console.log(person.age); // 22,不是24;
为obj重新定义了一个对象,并为其修改age的值为24,如果是按照引用传递的话,外部的person的age属性值也应修改为24,但是实际结果是22,说明即使在参数内部修改了参数的值,但是原始的引用仍然保持未变。实质上,这个变量引用是一个局部对象,在函数执行完毕后会立刻被销毁。
可以将函数的参数看成是局部变量
为了检测变量是基本类型还是引用类型,可以使用方法typeof 。如果变量是null,typeof会返回object。
var s = "Pengju";
var num = 1;
var b = true;
var u;
var n = null;
var o = new Object();
console.log( typeof s); // string
console.log( typeof num); // number
console.log( typeof b); // boolean
console.log( typeof u); // undefined
console.log( typeof n); // object
console.log( typeof o); // object
这里还有另外一个重要强大的工具,instanceof ,typepof只能告诉我们这个变量是对象,却不能确定类型,而 instanceof 却能告诉我们变量是何种类型的对象。
用法如下:s instance Array; //判断s是否是数组对象,是返回true,否则返回false
instanceof是用来检测对象的具体类型的,如果是基本数据类型,则始终返回false。
欢迎大家一起讨论,进步!!!