1、引用类型
引用类型是指封装了变量和对应函数的结构体,它是实例就是对象,类似于C++、Java中的类,但没有类的接口等。
创建方式一:
var obj = new Object();//new关键字 + 构造函数
obj.name = "noodles";//用.添加属性名
obj.age = 36;
alert(obj.name+","+obj.age);
创建方式二(字面量):
var obj = {//在表达式上下文用中括号{表示开始
name:"noodles",//用名值对方式 属性名与数值之间为: 不同名用逗号分隔
"age":28//属性名默认为字符串
}
alert(obj.name+","+obj.age + "," +obj.sex);//obj.sex返回undefined
区别:第二种写法代码量更少,而且用作函数实参时,提高可读性。
function print(person){
var str = "";
if( typeof person.name == "string"){
str = str + "name=" + person.name;
};
if(typeof person.age == "number"){
str = str + ",age=" + person.age;
};
alert(str);
}
print({name:"noodles",age:18});
print({name:"jack"});
前者主要用于定义确定的属性名,后者用于定义不固定的属性名。
备注:用typeof跟数值/变量可以检测具体数据类型,但不同引用类型对象,返回调用都是Object,并没有太大意义,所以一般用instanceof操作符,前面为数值/变量+instanceof+后面引用类型,判断后面的引用类型是否为前者的原型,如:
var obj = new Object();
alert(obj instanceof Object);//true
2、赋值
基本类型:实际数值
引用类型:指针(可以看做对象地址)。
3、作用域
代码执行时,变量有其它的作用域,一方面搜索变量(标识符)时先在最近的作用域查找,查找不到再去父作用域,这样提高了搜索效率;另外当执行工作离开变量最近作用域就被视为无效,内存会被回收,从而提高程序性能。
作用域分为:全局作用域(window对象)和函数作用域,代码块是没有作用域的,比如:
if(true){
var a = 3;
}
alert(a);//3
function f(){
var b = 3;
}
alert(b);//语法错误
作用域关系就像栈(入口朝下),执行时,首选全局作用域入栈,如果调用函数,则依次进栈,下面作用域可以(从下到上)依次调用上面作用域的变量,但上面作用域不能调用下面作用域的变量。
4、内存回收
程序自动回收,无需手动处理。
两种方式:
1、标记清除:标记为可清除,则回收变量。
2、引用计数:引用数为0,则回收变量。
第2种存在循环引用的情况,如
var obj1 = new Object();
var obj2 = new Object()
obj1.element1 = obj2;
obj2.element2 = obj1;
类似死锁的方式,则变量无法被回收。
处理方式:因为在函数作用域内变量在函数执行结束时会被销毁,所以无需手动处理,但全局变量为了避免循环引用,则把不用的引用类型变量赋值为null,如
obj1 = null;
obj2 = null;
这样则系统会定时进行内存回收。