美文网首页
作用域、环境、闭包

作用域、环境、闭包

作者: kingZXY2009 | 来源:发表于2017-04-12 17:35 被阅读8次

    今天开始一个小系列,我们从作用域开始,分别讲述作用域、作用域链、执行环境,最终为了学习理解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()以外的代码访问。

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

    欢迎加入技术QQ交流群:364595326

    相关文章

      网友评论

          本文标题:作用域、环境、闭包

          本文链接:https://www.haomeiwen.com/subject/zvgmattx.html