基本类型和引用类型
js中有5种基本数据类型和3种引用类型(数组,对象,函数)。
动态的属性
引用类型的值是内存中的对象,js中不允许直接访问内存中的对象。所以在操作的时候,实际访问的是对象的引用(给对象添加属性时操作的是对象本身)。
引用类型和基础类型不同的是,可以添加属性和方法,当然也可以改变和删除。例如:
var person = new Object();
person.name = "张三";
alert(person.name);//张三
但是如果给基础类型添加属性就会没有用,虽然不报错。
var name = "张三";
name.age = 27;
alert(name.age);//undefined
复制变量值
基础数据类型和引用类型在复制的时候也有不同。
基础数据类型是值得复制,复制之后变量的值是相互独立的。
而引用数据类型的复制是对象的引用。 复制结束后,二者都指向内存中的同一个对象,二者都可以操作那个对象。例如:
var obj1 = new Objeect();
var obj2 = obj1;
obj1.name = "张三";
alert(obj2.name);//张三
参数的传递
js中所有函数的参数都是按值传递的。
先看基础数据类型:
function addTen(num){
num = num+10;
return num;
}
var count = 10;
var result = addTen(count);
alert(result);//20;
alert(count);//10;
在函数执行过程中,会将count的值复制之后赋值给形式参数num(局部变量),之后num和count就没有联系了,所以执行函数之后并没有改变count的值。
再看看引用类型:
function setName(obj){
obj.name = "张三";
}
var person = new Object();
setName(person);
alert(person.name);//张三
在看到这的时候,我认为这不是引用的传递吗?那么再看下面的例子:
function setName(obj){
obj.name = "张三";
obj = new Object();//如果是按照引用传递的,这时候实际参数的引用发生变化,
obj.name = "李四";
}
var person = new Object();
setName(person);
alert(person.name);//张三
如果是按照引用传递的,那么person的引用就会在函数内发生变化,指向新的对象,从而改变name属性。但是person的name属性值没发生变化,说明不是按照引用传递的,那传递进来的是什么呢?
其实是引用的拷贝,所以传递进来之后,person和obj都指向指向那么堆中的实际对象,所以操作obj的时候,操作的也是那么对象,但是将obj重新赋值以后,obj就不指向堆中的对象了,所以操作obj就不会影响堆中的对象。
总的说就是引用类型作为参数传入函数,传的是个地址值,或者指针值,不是那个引用类型本身,它还好好的呆在堆内存呢。
检测类型
检测变量是的是基础数据类型,可以通过typeof操作符。如果变量是一个引用类型或者是null,会返回object.
但是它在检测引用数据类型时作用不大,因为它只会返回object,可有时候我们想知道到底是什么类型的对象,那么需要用到instanceof,这个操作符会通过原型链来识别。