美文网首页
JavaScript作用域和闭包

JavaScript作用域和闭包

作者: 铁匠简记 | 来源:发表于2018-08-06 01:15 被阅读16次

    闭包是函数的一种特性 一种现象,它不指代某个具体的语法、定义、概念等,要理解闭包就必须要清楚函数的作用域。

    1、词法作用域和激活对象

    JS中的函数是通过词法(语法、定义)划分作用域的 而不是动态创建作用域,这就是说函数是运行在它定义时的作用域,而不是执行时的作用域,例如:当嵌套函数从外围函数中被导出时,它的执行地发生了改变 但是作用域不变。
    在调用函数时,JS会首先将作用域设为定义时起作用的那个作用域,然后创建一个激活对象添加到作用域链的头部。函数体内的局部变量、定义时的形参、嵌套的函数,都是激活对象的属性。



    2、闭包的成因、原理

    当嵌套函数被导出时 定义的作用域是如何起作用的呢,这是因为函数定义时 会将作用域链保存起来 并且成为函数内部状态的一部分。
    这里嵌套函数返回的值,是存在于外围函数的激活对象中,可是当外围函数调用结束时,外围函数的激活对象会删除,从而使函数恢复之前的状态,这也是我们所期待的。
    但是嵌套函数改变了这一规则,当函数体内有嵌套函数时,如果嵌套函数只在函数体内使用(调用),嵌套函数随着外围函数退出(执行完毕)而结束,这也没有任何问题。
    可是,如果此时嵌套函数被导出或者存在其他引用,这时外围函数的激活对象就会保留下来。
    结果是外围函数的一次特定调用的激活对象中的值被保留下来,这种代码和作用域的综合体称为闭包。(解释了 此处为什么g调用能拿到值)。

    3、闭包的应用场景

    当嵌套函数被导出 或者存在其他引用时 会发生闭包,那么嵌套函数是如何被导出?
    1、将嵌套函数作为返回值;
    2、嵌套函数作为外部对象的属性(方法 属性值是一个匿名函数的是方法);
    3、使用自调用匿名函数,在闭包中能够帮助我们简化结构,便于处理;
    很多时候,我们期望给某段代码一个独立的执行环境,避免与其他部分的代码之间相互干扰,可以将它们放入一个函数中去执行。


    自调用匿名函数

    4、闭包的使用案例

    1、设置一个私有 且 持久存储的数据 例如 一个能不断自增的计数器
    很多时候 我们要给某个值自增需要把它设为全局变量 但是这样在全局裸露的环境中 值很容易被篡改 可以考虑将值放入一个局部环境中 存储 但是如何才能维持局部环境中的数据呢 只能通过闭包实现。





    2、定义一个访问器 给一个对象 添加一对get/set方法 用来操作对象的属性。



    相关文章

      网友评论

          本文标题:JavaScript作用域和闭包

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