javascript变量的做用域

基本类型和引用类型

基本类型值指的是简单的数据段,而引用类型值指的是那个可能由多个值组成的对象
讲一个值赋值给变量时,javascript解析器首先要肯定是基本类型仍是引用类型,基本数据类型能够直接操做保存在变量中的值,而引用数据类型的值是保存在内存中的对象,在操做对象是,实际上操做的是对象的引用而不是实际的对象javascript

变量的赋值

若是从一个变量上向另外一个变量上复制__基本数据类型__的值,会在变量对象上建立一个新值,而后把该值复制到新变量的位置上,这个很好理解,来看下例子:html

var num1 = 5;
var num2 = num1;

上面代码赋值的过程,以下图:java

 这是基本数据类型,而引用类型呢?其实一样会将原来变量上的值复制一份到新的变量当中,只不过,复制的实际上是原来变量的一个指针,而这个指针指向存储在堆中的一个对象。复制完成后,两个变量都指向了堆中的同一个对象,因此改变其中一个的值,会对另一个产生影响。有如下代码web

var obj1 = new Object(); 
var obj2 = obj1; 
obj1.name = "Nicholas"; 
alert(obj2.name);  //"Nicholas"

那么上面这段代码执行的过程以下图:浏览器

传递参数

在javascript里面,参数的传递都是按照值类型来传递的,即便你传入的是一个引用类型函数

function setName(obj) {     
    obj.name = "Nicholas"; 
}  
var person = new Object(); 
setName(person); 
alert(person.name);    //"Nicholas"

上面代码的返回结果貌似参数是引用类型的传递,由于开始person对象没有属性,调用了setName方法以后,给参数obj加上了name参数,而后外面的person打印person.name居然是有值的,这是很明显的引用传递的效果。可是不要被这种现象所迷惑,javascript在传递引用类型的参数的时候,只要这个参数不发生改变,那么仍是按照引用类型来处理,可是只有发生了改变效果就彻底不同了spa

function setName(obj) {     
    obj.name = "Nicholas";     
    obj = new Object();     
    obj.name = "Greg"; 
}  
var person = new Object(); 
setName(person); 
alert(person.name);    //"Nicholas" 

上面的例子能够看出区别,若是真的是引用传递,那么obj从新赋值,而且加上了name参数,最后person打印的应该是Greg的名字,可是结果倒是原来的值,只能说明javascript在这里挖了一个大坑,很是的迷惑人,不过只要搞清楚这点就好了。指针

执行环境及做用域

执行环境(execution context)定义了函数或者变量有权访问的其余数据,决定了他们各自的行为,每一个执行环境都有一个与之相关联的变量对象,环境中定义的全部的变量和函数都保存在这个对象中code

全局执行环境是最外围的执行环境,在web浏览器中,其实就是window对象,所以,全部全局变量和函数,都是做为window的属性和方法建立的,某个执行环境全部代码执行完毕以后,该环境被销毁,保存在其中的变量和函数定义也随之被销毁(全局执行环境直到应用程序退出,及浏览器关闭的时候才会被销毁)htm

每一个函数都有本身的执行环境,当程序执行到一个函数时,函数的环境会被建立出来,进入当前程序的流程,而在函数执行完成以后,程序流程将其弹出并销毁,把控制权返回给以前的执行环境

当代码在一个环境中执行时,会建立变量对象的__做用域链__,其根本意义就是在不一样层级的执行环境中,保证各个执行环境中的变量有序访问

相关文章
相关标签/搜索