zoukankan      html  css  js  c++  java
  • 作用域、闭包、模块

    当函数可以记住并访问所在的词法作用域时,就产生了闭包,即使函数是在当前作用域的外面执行。

      function foo(){
    
         var a = 2;
    
         function bar(){
    
           console.log(a)  
    
        };
    
        return bar;
    
    }
    
     var baz = foo();
    
      baz();   //2 这就是闭包

    在这个例子中,bar可以正常执行,它是在直接定义的词法作用域外执行的。通常,foo执行完后JS引擎会执行垃圾回收机制,但由于函数bar作为返回值赋值给baz,所以bar不会被回收,而bar覆盖了foo的内部作用域,故foo不会被回收,此时通过执行baz可以正常引用foo内部的变量,这就是闭包。

    闭包的作用:模块

    一个小例子:

       

    function foo(){
    
        var a=1,b=2;
    
         function doSome (){
    
            console.log(a);
    
        }
    
        function doOther(){
    
           console.log(b)
    
       }
    
       return {
    
          doSome:doSome,
    
          doOther:doOther
    
       }
    
    }
    
        var baz = foo();
    
        baz.doSome();  // 1
    
        baz.doOther(); // 2

    上面的例子中,foo的返回值是一个对象,对象的引用是内部的两个函数doSome和doOther,与上面同理,通过对函数的返回来实现随时访问foo内部的变量。

    假设我们把foo定义为立即执行函数,则可以实现对内部变量a和b的私有保护,如下:

    function foo(){
    
        var a=1,b=2;
    
         function doSome (){
    
            console.log(a);
    
        }
    
        function doOther(){
    
           console.log(b)
    
       }
    
       return {
    
          doSome:doSome,
    
          doOther:doOther
    
       }
    
    })();
    
        foo.doSome();  // 1
    
        foo.doOther(); // 2
    
     

     

    对于模块,每一次都需要对函数foo执行后才能引用其返回的对象,注意:每一次返回的对象值都是不同的,因为每一次函数执行时都会创造一个新的作用域,而返回的对象中的函数所覆盖的就是这个作用域。(函数定义和函数执行的作用域不同,每次执行函数都是一个新的作用域)假如在实际开发中只需实例化一次foo,那我们可以采用单例模式,即上面的立即执行函数,假如想根据不同参数执行不同代码,可以采用如下模式的代码:

    function foo(a){
    
        function doSome(){
    
          console.log(a)
    
       }
    
       return {doSome:doSome}
    
    };
    
    var baz = foo(1);
    
    var bar = foo(2);
    
    baz.doSome(); //1
    
    bar.doSome(); //2

     

    现代的模块化机制代码示例(具体使用和解释参见上卷第五章):

       

    var Mym = (function Manager(){
       var moul ={};
       function defined (name,deps,impl){
         for(var i = 0;i<deps.length;i++)
         deps[i] = moul[deps[i]]
       }
       moul[name] = impl.apply(impl,deps);
       function get(name){
         return moul[name]
      }
       return {
          defined:defined,
          get:get
    }
    })();
    
     

     

  • 相关阅读:
    mysql数据库主从同步复制原理
    NoSQL
    Mysqldump参数大全
    MySQL Show命令的使用
    学习shell脚本之前的基础知识
    详解MySQL大表优化方案
    sql索引的优缺点
    [C#] 取得每月第一天和最後一天、某月总天数
    Easy ui DateBox 控件格式化显示操作
    StudioStyle 使用 厌倦了默认的Visutal Studio样式了,到这里找一个酷的试试
  • 原文地址:https://www.cnblogs.com/Darlietoothpaste/p/6387091.html
Copyright © 2011-2022 走看看