作用域、执行环境、闭包(一)

本文也同步发表在我的公众号“我的天空

 

 

 

今天开始一个小系列,我们从作用域开始,分别讲述作用域、作用域链、执行环境,最终为了学习理解JavaScript中一个很经典的概念:闭包

 

闭包是JavaScript中比较高级的概念和技巧,也是难理解的部分,必须熟练掌握函数表达式、作用域、变量的生存周期等概念后,才能掌握闭包的技巧。

 

作用域

 

我们已经知道了变量的概念,不管变量是基本数据类型还是引用类型,其都有一个作用范围,称之为作用域,超出该变量的作用域,则不能被访问,否则将会异常。如果该变量能被所有代码访问,称之为全局变量,其作用域为整个代码环境,反之为局部变量,其作用域为局部。可以将作用域的机制想象为行政管辖范围:县长只能管辖整个县、而市长可以管辖整个市、省长可以管辖整个省。

 

我们先来看以下代码:

 

var name=""张三";

 

function setname(){
    name="李四";
}

function showname(){
    alert(name);
}
showname();      //显示“张三”
setname();
showname();      //显示“李四”

 


分析以上代码,我们首先声明了一个变量name并给其赋值为“张三”,由于该变量的声明不在任何函数内,因此其为全局变量,作用域为全局环境,可在整个代码中对其访问,所以可以在函数setname()对其改写,并在函数showname()中对其访问。

 

接下来对代码做如下修改:

 

function setname(){
    var name="李四";
    alert(name);
}

function showname(){
    alert(name);
}
showname();      //显示空
setname();       //显示“李四”
showname();      //显示空


我们把变量name的声明移至函数setname()内部,因此name的作用域范围只是函数setname()内部,而在函数showname()中访问不到变量name,因此显示为空。

 

继续看以下的代码:

 

function setname(){
    var name="李四";
    alert(name);
}

function setothername(){
    var name="张三";
    alert(name);
}
setname();             //显示“李四”
setothername();       //显示“张三”

 

虽然在函数setname()和setothername()都声明了name变量,但由于两个变量name的作用域均为函数内部,因此这两个变量name仅仅是名称相同而已,实际上是完全不同的两个变量,具有了不同的值。

 

接下来我们看一个较复杂的例子,函数内嵌套函数,可以更好的诠释变量声明的位置如何决定其所拥有的作用域:

 

var name="张三";
function changename(othername){
    function swapname(){
        var tempname=othername;
        othername=name;
        name=tempname;
        //此处可以访问name、tempname、othername
    }
    swapname();
    //此处可以访问name、othername,但不能访问tnepname
}
changename("李四");             
alert(name);      //显示“李四”
//此处仅可访问name

 

分析以上代码,这是个改变姓名的函数,首先我们声明了全局变量name,其能被所有代码访问,接下来声明函数changename(),其传入参数为othername,因此函数changename()可以访问name、othername两个变量,在函数changename()中又声明了函数swapname(),在其内部又声明了局部变量tempname,所以函数swapname()可以访问name、othername、tempname三个变量。但变量tempname不能被函数swapname()以外的代码访问,同样传入参数othername也不能被函数changename()以外的代码访问。

 

下一讲我们将学习执行环境、作用域链。

 

posted @ 2017-04-12 17:22  我的天空-老潘  阅读(230)  评论(0编辑  收藏  举报