JS之执行环境,作用域详解

在《Javascript高级程序设计》这本书中学到的知识,觉得对于JS学习还是有很大帮助的,所以就写上来跟大家分享一下。

首先我们来看一下执行环境。用例子来说明:

var backgroundColor='red';
function changeColor(){
    if(backgroundColor=='red'){
        backgroundColor='blue';
            }

}
changeColor();
alert(backgroundColor);

上面的结果是blue。然而,我们分析一下它的执行过程。每一个函数都有执行环境,当这个函数执行的时候,这个执行环境就会进入环境栈中,函数结束后就会被栈弹出。在这个环境中会产生一个AO(Active 0bject)对象,最开始这个AO对象只有一个变量:argument,但随着作用域链,backgroundColor这个对象也存在了AO对象的一个变量中,所以,changeColor的执行过程是这样的:

①产生一个AO对象,一开始只有argument变量: ActiveObject{argument}
②沿着作用域链,ActiveObject{argument,backgroundColor:'blue'}
③接着就弹出对话框,其中的信息是ActiveObject.backgroundColor,也就是blue。

上面不断提到作用域链的问题,到底什么是作用域链呢?我们首先来看一下作用域,换一个例子:

var color='blue';
function a(){
    var backColor='red';
    function b(){
        var fontColor='black';
    //这里能够访问color,backColor,fontColor
    }
    //这里能够访问color backColor 但不能访问fontColor
    b();
}
//这里只能够访问 color
a();

从上面的例子注释,我们可以很容易理解作用域的概念,就是变量在哪个地方能够被访问。要注意,js是没有块级作用域的。然后,我们来说说开始的例子作用域链的问题,产生AO对象的时候,它会在函数changeColor中找变量,发现里面并没有声明任何变量(即没有var一个变量),所以,沿着作用域链,查找比changeColor范围还要广的作用域,即是全局作用域,就发现了backgroundColor。这就是作用域链:保证对执行环境有权访问的所有变量和函数的有序访问。

最后,我们来看一看一个经典的面试题

var str='global';
function a(){
    alert(str);
    var str='local';
    alert(str);
}
a();

大家想到结果没有? 第一个是undefined ,第二个是local。 有没有大惊小怪?
不过相信大家看了上面的知识,理解这道题就没什么难度了。

大家不要被全局变量str="global"误导了,其实这个并没什么作用
有作用的是a函数里面的var str='local',在变量定义的时候,其实编译器会先把变量声明了 再给它赋值的,也就是其实上面的代码是这样的:
function a(){
    var str;
    alert(str);
    str='local';
    alert(str);
}
接着,就产生一个AO对象,里面首先是alert(AO.str)一开始的时候,str=undefined的所以会输出undefined,接着str赋值为local,就会输出AO.str='local'.

好了,这部分大概就这么多了,大家可以把这个面试里a函数里面的var去掉,看看结果什么,如果和你预想一样,这部分我相信你也能够理解了。

发布了29 篇原创文章 · 获赞 15 · 访问量 5万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章