一、基本类型和引用类型的值
javascript的变量只是在特定时间用于保存特定值的一个名字。
基本类型值:简单的数据段。
引用类型值:多个值构成的对象。
1、动态的属性
对于引用类型值,可以改变它的属性和方法,而基本类型值不能。
如,引用类型值:
1 var Person = new Object(); 2 Person.name = 'zhangsan'; 3 alert(Person.name);/ /zhangsan
基本类型值:
1 var name = 'zhangsan'; 2 name.age = '19'; 3 alert(name.age)';//undefined
2、复制变量值
基本类型值:
var num1 = 12; var num2 = num1;//12
num2 = 10;
alert(num1);//12
此时num2中也保存了12,但是和num1中的12是完全独立的,两个变量操作不会相互影响。
引用类型值:
1 var obj1 =new Object(); 2 var obj2 = obj1; 3 obj1.name = 'zhangsan'; 4 alert(obj2.name);//zhangsan
5 obj2.name = 'lisi';
6 alert(obj1.name)//lisi
对于引用类型值,obj2中的name实际上是一个指针,指向存储的堆中的唯一对象,如果改变其中一个,另外一个也会改变。
3、传递参数
ECMAscript中所有函数的参数都是按值传递的。
在向参数传递基本类型的值时,被传递的值会被复制给一个局部变量。
在向参数传递引用类型的值时,会把值在内存中的地址复制给一个局部变量,这个局部变量的变化会反映在函数的外部。
1 function Add(num){ 2 num += 10; 3 return num; 4 } 5 var count = 10; 6 var result = Add(count); 7 alert(count); //10 8 alert(result); //20
在上述代码中,在Add方法中,num被加上了10,但是这个改变并不会对count值造成影响。
如果传递的参数是一个对象。
1 function name(obj){ 2 obj.name = 'zhangsan'; 3 } 4 var person = new Object(); 5 name(person); 6 alert(person.name); //'zhangsan'
在上述代码中创建了一个对象,并将其保存在了变量person中,然后变量被传递到name()函数中,被复制给obj。在函数内部,obj和person引用的是同一对象,所以,在函数内部为obj添加name属性后,外部的person也会有所反映。
4、检测类型
typeof() 可以检测一个变量是不是基本数据类型。
二、执行环境及作用域
每个函数都有自己的执行环境,当执行进入一个函数时,函数的环境会被推入一个环境栈,在函数执行之后,栈将其控制权返还给之前的执行环境。当代码在一个环境中执行时,会创建变量对象的作用域链,保证执行环境有权访问的所有变量和函数有序访问。
如下面的代码:
var color = 'blue'; function color(){ var color2 = 'red'; function color2(){ var color3 = color2; color2 = color; color = color3; //这里可以访问color color2 color3 } color2(); // 这里访问 color color2 } color(); //这里只能访问color
1、延长作用域链
try catch 语句的catch块。
with语句
2、没有块级作用域
使用var申明的变量会被自动添加到最接近的环境中,如果初始化变量时没有使用var,改变量自动被添加到全局环境。
function add(num1,num2){ var sum = num1 + num2; return sum; } var result = add(10,20); //30 alert(sum); //sum不是有效的变量,会报错。
查询标识符:当环境要读取或写入一个标识符时,要通过搜索来明白这个标识符代表什么
搜索从作用域前端开始,向上级逐步查询,如果在局部环境中查到则停止,没查到则向上级查找。
var color = ‘blue’; function getColor(){ return color; } alert(getColor()); //blue
上述例子的搜索过程