做用域与做用域链

 

javascript是一种过程式编程的脚本语言,对于过程式编程来讲,代码执行的时间与数据标识的空间是不可分割的,咱们只有把指令执行的具体时刻与标识映射的具体地址结合起来,才能肯定程序在执行瞬间的上下文状态。因而,代码时刻和数据标识的结构就造成了javascript做用域的概念。javascript中对做用域的定义是变量存在的执行环境,而在这里还包含了代码执行的时刻,即二者的结合。javascript

在一个做用域中的上下文状态,在另外一个做用域来讲是不适用的。java

任何一个程序都会在一个原始的环境中开始运行,这个原始的环境被称为全局环境。全局环境中包含了一些预约义的元素,这些元素对于咱们的程序来讲是天然存在的,它们原本就在那里,咱们拿来便可使用。编程

在javascript里的全局环境就是一个对象,这个对象是javascript运行环境的根。对于浏览器中的javascript来讲,这个根就是window对象;对于全局环境中的javascript语句,window对象就是当前的做用域。浏览器

在全局环境中,当咱们写下: var color = "red"; 这就至关于在window做用域中定义了一个变量color,并为它赋值为red ,可是当咱们在全局环境中写下: color = "red"; 这就至关于咱们为window对象定义了一个属性color,且color属性的值为red,在全局环境里,window做用域的一个变量color和window对象的一个属性几乎是等价的;若是是在函数体内部的语句,那就彻底不同了。例如:app

<script type="text/javascript">函数

var color = "red";对象

mycolor = "green";ip

alert( color + "and" + mycolor);  //  red and green作用域

changecolor();  //  调用函数io

function changecolor(){

  alert( "The apple is" + color);  // The apple is undefined

  alert( "The tree is green" + mycolor);   // The tree is green 

  var color = "bule";

  mycolor = "pink";

  alert(color);  //blue

  alert(mycolor)  //pink

}

alert( color + "and" + mycolor);  //red and pink

</script>

从例子能够看出,使用var定义的变量在全局环境中和函数体内部是彻底不同的两个东西。因此,咱们只须要记住:var定义的是做用域中的一个变量,而没有var的标识符多是全局根对象的一个属性。当代码运行在全局做用域时,做用域的根对象就是window,因此在全局执行环境时有没有var都无所谓。

  当代码运行进入一个函数的时,javascript会建立一个新的做用域,来做为当前做用域的子做用域。而后将当前全局做用域切换为这个新建的子做用域,开始执行函数逻辑。

在第一步预编译分析中,javascript执行引擎将全部定义式函数直接建立为做用域上的函数变量,并将其值初始化为定义的函数代码逻辑,也就是为其创建了可调用的函数变量。而对于全部var定义的变量,也会在第一步的预编译中建立起来,并将初始值设为undefined。

  随后,javascript开始解释执行代码。当遇到对函数名和变量名的使用时,javascript执行引擎会首先在当前做用域中查找函数或变量,若是没有就到上层做用域中查找。所以,前面的语句引用后面语句定义的var变量时,该变量其实已经存在,只是初始值为undefined。

  因此说,用var定义的变量只对本做用域有效,尽管上层做用域中有同名的东西,都与本做用域中的var变量无关。推出本做用域以后,回到原来的做用域中该是什么就是什么。

  其实,函数在每次调用的时候都会产生一个子做用域,推出函数时,这个子做用域就会消失,下次调用相同函数时有是另外一个子做用域了。在运行的函数内部再调用另外的函数时,有产生另外一个做用域,这样随着函数调用的深刻就会造成做用域链,在插找变量的时候,搜索机制就会沿着做用域链一层一层向上搜索。

  像上面的例子中,做用域链就是changecolor()对象、全局的window对象。

若是changecolor函数内部没有 var color = "blue";这条语句,那么当咱们使用color变量时,就会沿着做用域链向上查找color变量,这是会返回red而不是undefined。可是咱们在函数内部使用var定义了color变量,且在alert()方法后面,这是函数内部的做用域中color变量已经存在,这是初始化值为undefined。

相关文章
相关标签/搜索