zoukankan      html  css  js  c++  java
  • JavaScript 函数作用域和闭包

    函数作用域和闭包
     词法作用域  
      它们在定义它们的作用域里运行,而不是在执行的作用域运行,但是只有在运行时,作用域链中的属性才被
    定义(调用对象),此时,可访问任何当前的绑定。
      调用对象      
      当JavaScript解释器调用一个函数,它首先将作用域设置为定义函数时起作用的那个作用域链,
    然后在作用域最前面加上一个新的对象(调用对象)
    所以函数内定义的局部变量以及函数的参数,都添加到调用对象的属性上,这意味着,它们隐藏了作用域链上更上层的任何的同名的属性
    (变量寻找路径)
       作为闭包的嵌套函数
    嵌入的函数在与它们定义的同一个词法作用域里调用。
    外层函数被调用时,外层函数的作用域包含 外层函数的调用对象,以及全局对象。
    嵌套函数被调用时,作用域链包含三个对象:嵌套函数的调用对象,外层函数的调用对象,全局对象。
     
    1、当没有嵌套函数时,作用域链是对调用对象的惟一的引用,当函数退出结束时,调用对象也从链中移除了,也就没有对它的引用了,
    最终被垃圾回收,释放内存。
     
    2、如果创建了一个嵌套函数时,对嵌套函数的惟一的引用在嵌套函数的调用对象中(情况同上),当外围函数返回时,嵌套函数与外围函数的调用引用相互引用(嵌套函数当作此调用对象的属性,此调用对象相当于此函数的局部全局对象),但没有其他的东西引用它们二者,对这两个对象都可进行垃圾加收
     
    3、如果把一个嵌套函数的引用保存到一个全局作用域中,情况又不同了(方法是:通过使用嵌套函数作为外围函数的返回值,并存储在一个全局对象的属性中,或存在某个外部对象的属性上来做到这一点,)。
     
    在这种情况下,有一个对嵌套函数的外部引用,并且将其保留给外围函数的调用对象,此时,当外围函数返回时,不能通过垃圾收集对外围函数的一次特定调用对象进行清除,因为这个调用对象是嵌套函数的局部全局对象,直到这个对嵌套函数的引用消除为此。
    那么外围函数的参数和局部变量的名字和值在这个对象中得以维持。嵌套函数的调用对象,它所定义的属性是对嵌套函数任何调用的作用域链的一部分。
    如果两个嵌套函数均被全局引用,这两个函数共享同一个外围函数的调用对象,两个函数对此对象的修改,会影响另一个函数的调用对象(作用域链),当然如果只有一个被全局引用,在这个函数中执行另外一个,也是这种情况,相互影响。
     
    JavaScript函数是将要执行的代码以及执行这些代码的作用域构成一个综合体。
     
    当嵌套函数被导出到它所定义的作用域外时,以这种方法调用,叫做一个闭包。
     
     1 //闭包 ,嵌套函数被导出到它所定义的作用域外时,以这种方法调用,叫做一个闭包
     2 function outA() {
     3     var x = 0;
     4     function inA() {
     5         x += 1;
     6         console.log("inA:x=" + x);
     7     }
     8     return inA;
     9 }
    10 var funa = outA();
    11 funa();
    12 funa();
    13 
    14 
    15 
    16 function outC(obj) {
    17     var x = 0;
    18     function inA() {
    19         x += 10;
    20         console.log("inA:x=" + x);
    21     }
    22     function inB() {
    23         x += 2;
    24         console.log("inB:x=" + x);
    25     }
    26     obj.funa = inA;
    27     obj.funb = inB;
    28 }
    29 var o = new Object();
    30 outC(o);
    31 o.funa();
    32 o.funb();

    输出:
    "inA:x=1"
    "inA:x=2"
    "inA:x=10"
    "inB:x=12"

     注:还差函数的使用与调用,就与Arguments合并
     
  • 相关阅读:
    学生免费注册Pycharm
    CSS笔记
    加载CIFAR数据集时报错的大坑
    发布小程序
    微信中的动图如果发朋友圈
    安卓第一个小项目
    转换小写字母
    1小时搞定vuepress快速制作vue文档/博客+免费部署预览
    干货满满!如何优雅简洁地实现时钟翻牌器(支持JS/Vue/React)
    JavaScript 加减危机——为什么会出现这样的结果?
  • 原文地址:https://www.cnblogs.com/tlxxm/p/4361937.html
Copyright © 2011-2022 走看看