基本数据类型:Underfined,Null,Boolean,Number和String.
引用类型的值是保存在内存中的对象。(JS不允许直接访问内存中的位置)
在操作对象时,实际上是在操作对象的引用而不是实际上的对象。
动态属性
定义引用类型的值
var person=new Object()
person.name="Nicholas";//person类型的属性name赋值为"Nicholas"
alert(person.name)//"Nicholas"
不可以给基本类型的值添加属性
var name="Nichas";
name.age=27;
alert(name.age);//undefined
复制变量值
基本类型值
var num1=5;
var num2=num1;
//num1与num2可以参与任何操作而不会相互影响。
引用类型值
var obj1=new object();
var obj2=obj1;
obj1.name="Nicholas";
alert(obj2.name);//"Nicholas"
//obj1与obj2实际上引用的是同一个对象,改变其中一个变量,就会影响到另一个变量。
传递参数
function addTen(num){
num+=10;
return num;
}
var count=20;
var result=addTen(count);
alert(count);//20 ,没有变化。
alert(result);//30
这里的函数addTen()有一个参数num,而参数实际上是函数的局部变量。
function setName(obj){
obj.name="Nicholas";
}
var person=new Object();
setName(person);
alert(person.Name);//"Nicholas"
//创建了一个对象,并将其保存在了变量person中。然后,这个对象被传递到setName()函数中。
后就被复制给了obj;
function setName(obj){
obj.name="Nicholas";
obj=new Object();
obj.name="Greg";
}
var person=new Object();
setName(person);
alert(person.Name);//"Nicholas"
//此段代码说明即使在函数内部修改了参数的值,但原始的引用仍然保持未变。
检测类型
检测引用类型的值;
result=variable instanceof constructor;
例:
alert(person instanceof Object); //变量person是Object吗?
alert(colors instanceof Array);//变量colors是Array吗?
//在检测一个引用类型的值和Object构造函数时,instanceof操作符始终会返回true,
如果使用instanceof操作符检测基本类型的值,则该操作符始终会返回false;因为基本类型不是对象。
执行环境与作用域
例
var color="blue";
function changeColor(){
var anotherColor="red";
function swapColor(){
var tempColor=anotherColor;
anotherColor=color;
color=tempColor;
//这里可以访问color,antherColor和tempColor
}
//这里可以访问color和anotherColor,但不能访问tempColor
swapColor();
}
//这里只能访问color
changeColor();
有三个执行环境,全局环境,changeColor()的局部环境和swapColor()的局部环境。
全局环境中有一个变量color和一个函数changeColor().changeColor()的局部环境中有一个名为
anotherColor的变量和一个名为swapColor()的函数,但他可以访问全局环境中变量color。swapColor()
的局部环境中有一个变量tempColor.该变量只能在这个环境中访问到。
延长作用域链
可以使用 1.try-catch语句的catch块
2.with语句。
javaScript:作用域对应ECMAScript的执行环境。
没有块级作用域
for(var i=0;i<10;i++){
doSomething(i);
}
alert(i);//10
对于有块级作用域的语言来说,for语句初始化变量的表达式所定义的变量,
只会存在与循环的环境之中,而对于JS,由for语句创建的变量i即使在for
循环执行结束后,也依旧会存在于循环外部的执行环境中。
声明变量
function add(num1,num2){
var sum=num1+num2;
return sum;
}
var result=add(10,20);//30
alert(sum);//由于sum不是有效的变量,因此会导致错误
function add(num1,num2){
sum=num1+num2;
return sum;
}
var result=add(10,20);//30
alert(sum);//30
//在上面这两个例子中,例子一在函数中定义了sum,故其执行环境
是函数环境,alert()无法访问此变量。出错。例子二没有定义sum,故默认其执行环境为
全局环境。alert()就可以访问到了。
查询标识符
例子
var color="blue";
function getColor(){
return color;
}
alert(getColor());//"blue"
首先搜索getColor()的变量对象,查找其中是否包含一个名为color
的标识符,在没有找到的情况下,搜索继续到下一个变量对象(全局环境的变量对象)
之后找到名为color的标识符。
在搜索过程中如果局部环境中存在着同名标识符,就不会使用位于父环境的标识符。
垃圾收集
1.标记清除
运行时会给存储在内存中的所有变量都加上标记;
然后,它会去掉环境中的变量以及被环境中的变量引用的变量
的标记。而在此之后的变量将被视为被删除的变量。
2.引用计数:
当声明了一个变量并且将一个引用类型值赋给该变量时,这个值就是1,
如果同一个值又被赋给另一个变量,则该值的引用次数加1.相反;如果
包含对这个值引用的变量又取了另一个值。则这个值的引用次数减1,当这个值
的引用次数变成0时,则说明没有办法再访问这个值,故可以将其占用内存空间收回。
管理内存
例
function createPerson(name){
var localPerson=new Object();
localPerson.name=name;
return localPerson;
}
var globalPerson=creatPerson("Nicholas");
//手工解除globalPerson的引用。
globalPerson=null;
//本例中共有两个变量 localPerson,globalPerson;
loaclPerson在creatPerson运行完毕后就离开了其执行环境。
不需显示为其解除引用,而对于全局变量globalPerson就需要
手工为其解除引用。