JavaScript作用域链使用介绍

之前写过一篇JavaScript 闭包究竟是什么的文章理解闭包,觉得写得很清晰,可以简单理解闭包产生原因,但看评论都在说了解了作用域链和活动对象才能真正理解闭包,起初不以为然,后来在跟公司同事交流的时候发现作用域和执行环境确实很重要,又很基础,对理解JavaScript闭包很有帮助,所以在写一篇对作用域和执行环境的理解。

作用域

作用域就是变量和函数的可访问范围,控制着变量和函数的可见性与生命周期,在JavaScript中变量的作用域有全局作用域和局部作用域。

单纯的JavaScript作用域还是很好理解的,在一些类C编程语言中花括号内的每一段代码都有各自的作用域,而且变量在声明它们的代码段外是不可见的,称之为块级的作用域,JavaScript容易让初学者误会的地方也在于此,JavaScript并没有块及的作用域,只有函数级作用域:变量在声明它们的函数体及其子函数内是可见的。

变量没有在函数内声明或者声明的时候没有带var就是全局变量,拥有全局作用域,window对象的所有属性拥有全局作用域;在代码任何地方都可以访问,函数内部声明并且以var修饰的变量就是局部变量,只能在函数体内使用,函数的参数虽然没有使用var但仍然是局部变量。

复制代码 代码如下:


var a=3; //全局变量
            function fn(b){ //局部变量
                c=2; //全局变量
                var d=5; //局部变量
                function subFn(){
                    var e=d; //父函数的局部变量对子函数可见
                    for(var i=0;i<3;i++){
                        console.write(i);
                    }
                    alert(i);//3, 在for循环内声明,循环外function内仍然可见,没有块作用域
                }
            }
            alert(c); //在function内声明但不带var修饰,仍然是全局变量

只要是理解了JavaScript没有块作用域,简单的JavaScript作用域很好理解,还有一点儿容易让初学者迷惑的地方是JavaScript变量可函数的与解析或者声明提前,好多种叫法但说的是一件事情,JavaScript虽然是解释执行,但也不是按部就班逐句解释执行的,在真正解释执行之前,JavaScript解释器会预解析代码,将变量、函数声明部分提前解释,这就意味着我们可以在function声明语句之前调用function,这多数人习以为常,但是对于变量的与解析乍一看会很奇怪

复制代码 代码如下:


console.log(a); //undefined
            var a=3;
            console.log(a); //3
            console.log(b); //Uncaught ReferenceError: b is not defined


     上面代码在执行前var a=3; 的声明部分就已经得到预解析(但是不会执行赋值语句),所以第一次的时候会是undefined而不会报错,执行过赋值语句后会得到3,上段代码去掉最后一句和下面代码是一样的效果。

复制代码 代码如下:


var a;
            console.log(a); //undefined
            a=3;
            console.log(a); //3

然而
如果只是这样那么JavaScript作用域问题就很简单了,然而由于函数子函数导致的问题使作用域不止这样简单。大人物登场——执行环境或者说运行期上下文(好土鳖):执行环境(execution context)定义了变量或函数有权访问的其它数据,决定了它们的各自行为。每个执行环境都有一个与之关联的变量对象(variable object, VO),执行环境中定义的所有变量和函数都会保存在这个对象中,解析器在处理数据的时候就会访问这个内部对象。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wdzxww.html