1.基本类型和引用类型
这里进一步强调一下复制变量和传递参数的问题。
(1)基本类型的复制,会在变量对象上创建一个新值,然后把该值复制到为新变量分配的位置上。向函数参数传递基本类型的值,被传递的值会赋值给arguments对象中的一个元素,因此函数中使用的参数是一个函数的局部变量。
function addTen(num){
num += 10;
return num;
}
var count = 20;
var result = addTen(count);
alert(count);//20
alert(result);//30
(2)引用类型的复制,同样会将储存在变量对象中的值复制一份到位新变量分配的空间中,不同的是,这个值的副本实际上是一个指针,指向存储在堆中的一个对象。复制结束以后,两个变量实际上将引用同一个对象,因此改变其中一个变量就会影响另外一个变量。像参数传递应用类型的值时,会把这个值在内存中的地址复制给一个局部变量,因此这个局部变量的变化会反映在函数的外部。
因为在局部作用域中修改的对象会在全局作用域中反映出来,可能会误解位参数时按引用传递的。我们来看下面一个例子。将全局中的obj类比上图的obj1,将中函数中的obj类比obj2,相当于 obj1和 obj2先开始指向同一个对象,并为之添加一个name为wk的属性。但是之后obj2被赋予了一个新的对象,所以后面的操作对obj1没有影响,而obj2作为一个局部变量在函数执行完毕以后也会被立即销毁。
function setName(obj){
obj.name = "wk";
obj = new Object();
obj.name = "yxy";
}
var person = new Object();
setName(person);
alert(person.name); //wk
2.执行环境及作用域
- 内部环境可以通过作用域链访问所有的外部环境,但是外部环境不能访问内部环境中的任何变量和函数。
- 环境之间的联系时线性、有次序的。
- 每个环境可以向上搜索作用域链,以查询变量和函数名。
- 任何环境不能通过向下搜索作用域链而进入另外一个执行环境。
var color = "blue";
function changeColor(){
var anotherColor = "red";
function swapColors(){
var tempColor = anotherColor;
anotherColor = color;
color = tempColor;
//可以访问color、anotherColor、tempColor
}
//可以访问color、anotherColor
swapColors();
}
//可以访问color
changeColor();