你的位置:首页 > Java教程

[Java教程]Js作用域链


作用域链

如果想要学好Javascript,有三个地方必须要认真掌握:两链一包

两链:作用域链与原型链

一包:Javascript中的闭包

1、作用域

在Javascript中没有块级作用域,对作用域的划分都是通过function函数来实现的。在函数外部的区域就是全局作用域,在函数内部的区域就是局部作用域。

2、全局变量与局部变量

在全局作用域中定义的变量就是"全局变量"

在局部作用域中定义的变量我们就称之为"局部变量"

但是全局变量与局部变量也是相对而言的,也会存在以下特殊形式:

3、变量与作用域之间的访问关系

在全局作用域中可以引入全局变量,在局部作用域中即可以引用全局变量也可以引用局部变量。

但是在全局作用域是不能访问局部变量的,如下图所示:

主要原因有二:

① 作用域不允许

② 受到Javascript垃圾回收机制的影响

Javascript垃圾回收机制:

当函数执行完毕后,其内部的所有局部变量都会自动被内存所回收,这就是垃圾回收机制。

 

问题:为什么在局部作用域中可以引用全局变量呢?

答:受到作用域链的影响

4、作用域链

在局部作用中,引用一个变量后,系统会自动在当前作用域中寻找var的声明语句,如果找到则直接使用,否则继续向上一级作用域中去寻找var的声明语句,如未找到,则继续向上级作用域中寻找…直到全局作用域中如还未找到var的声明语句则自动在全局作用域中声明该变量。我们把这种链式的查询关系就称之为"作用域链"。

 

例1:使用作用域链的原则解析以下代码

运行结果:10

解析:当我们执行display函数时,系统会自动执行第13行代码,由于在局部作用域中引用了一个变量i,所以根据作用域链的原则,系统首先在当前作用域中寻找var的声明语句,但未找到,所以继续向上一级作用域中寻找var的声明语句,在全局作用域中找到了var的声明语句,所以直接弹出结果10。

 

例2:使用作用域链原则解析以下代码的执行结果

运行结果:100

解析:系统首先在全局作用域中定义一个全局变量var i = 10,然后在12行代码中定义一个函数fn1,然后继续向下执行,在第24行执行fn1函数,然后进入到fn1函数内部执行代码,在第13行中定义一个局部变量var i=100,然后继续定义fn2函数并在第22行执行,然后执行fn2函数并在其内部定义并执行fn3函数,由于在fn3函数内部使用了变量i,所以其会自动在当前作用域中寻找var的声明语句,未找到则进入到fn2中去寻找,也未找到,继续向上一级fn1函数中寻找,找到var i=100,所以直接使用该变量,整个程序的执行结果为100。

 

例3:改进上题,说出程序的执行结果

在Javascript中,代码都是从上往下一行一行执行的,所以以上代码首先在第10行定义一个全局变量i等于10,然后在12行代码定义一个fn1函数并在24行执行,然后进入到fn1函数的内部继续执行,由于在第13行使用了一个变量i,但是其并未声明,所以根据作用域链的原则,系统会自动在当前作用域中寻找var的声明语句,未找到则自动向上一级作用域中去寻找,找到了var i = 10则直接使用,覆盖全局中的i,然后代码继续向下执行定义fn2并执行,定义fn3并执行,由于在fn3函数的内部,又引入了变量i,根据作用域链的原则,继续向上寻找,直到全局作用域,由于全局中的变量i已被覆盖为100,所以最终结果为100。

5、作用域链原理图