zoukankan      html  css  js  c++  java
  • 便写高质量JavaSript的68个高效方法 >> 二章:变量作用域 >> 第11条:熟练掌握闭包

    二章

    第11条:熟练掌握闭包

    理解闭包的三个基本事实:

    1. javaSricpt允许你引用在当前函数以外定义的变量。

    2. 即使外部函数已经返回,当前函数仍然可以引用在外部函数所定义的变量。

    3. 闭包可以更新外部变量的值。

    1. javaSricpt允许你引用在当前函数以外定义的变量。

    function makeSandwich(){
    
      var magicIngredient = "peanut butter";
    
      function make(filling){
    
        return magicIngredient + "and" + filling;
    
      }
    
      return make("jelly");
    
    }
    
    makeSandwich();      //"peanut butter and jelly"

    请注意内部的make函数是如何引用定义在外部makeSandwich函数内的magicIngredient变量的。

    2. 即使外部函数已经返回,当前函数仍然可以引用在外部函数所定义的变量。

    function sandwichMaker(){
    
      var magicIngredient = "peanut butter";
    
      function make(filling){
    
        return magicIngredient + "and" + filling;
    
      }
    
      return make;
    
    }
    
    var f = sandwichMaker();
    
    f("jelly");    //"peanut butter and jelly"
    
    f("bananas");     //"peanut butter and bananas"
    
    f("marshmallows")     //"peanut butter and marshmallows"

    与 1 的不同之处:f的值为内部的make函数,调用f实际上是调用make函数。

            即使sandwichMaker函数已经返回,make函数仍能记住magicIngredient的值。

    这是如何工作的:JavaScript的函数值包含了比调用他们时执行所需要的代码还要多的信息。而且,JavaScript函数值还在内部存储他们可能会引用的定义在其封闭作用域的变量。那些在其所涵盖的作用域内跟踪变量的函数被称为闭包。

    make函数就是一个闭包,其代码引用了两个外部变量:magicIngredient 和filling。每当make函数被调用时,其代码都能引用到这两个变量,因为该闭包存储了这两个变量。

    函数可以引用在其作用域内的任何变量,包括参数和外部函数变量。

    更加通用的sandwichMaker函数

    function sandwichMaker(magicIngredient){  
      function make(filling){     
        return magicIngredient + "and" + filling;   
      }   return make; 
    } 
    var handAnd = sandwichMaker("ham"); 
    handAnd("cheese");        //"ham and cheese" 
    handAnd("mustard");             //"ham and mystard" 
    var turkeyAnd = sandwichMaker("turkey"); 
    turkeyAnd("Swiss");    //"turkey and Swiss"
    turkeyAnd("Provolone");  //"turkey and provolone" 

    函数表达式(更方便地构建闭包的字面量语法)

    function sandwichMaker(magicIngredient){  
      function make(filling){     
        return magicIngredient + "and" + filling;   
      }  
    } 

    3. 闭包可以更新外部变量的值。

      实际上,闭包存储的是外部变量的引用,而不是他们的值的副本。

      因此对于任何具有访问这些外部变量的闭包,都可以进行更新。

    一个简单的惯用法box对象的例子。(他存储了一个可读写的内部值)

     

     function box(){
    
        var val = unfefined;
    
         return {
    
            set:function(newVal){ val = newVal; },
    
            get:function(){ return val; },
            type:function(){ return val; }
         };
      }
    
      var b = box();
    
      b.type();     //"undefined"
      b.set(98.6);     
    
      b.get();    //98.6
      b.type();     //"number"
    这个例子产生了一个包含三个闭包的对象。
    这三个闭包是set、get、type属性。他们都共享访问val变量。set闭包更新val的值,随后调用get和type查看更新的结果。

    提示:

    • 函数可以引用定义在其外部作用域的变量。
    • 闭包比创建他们的函数有更长的生命周期。
    • 闭包在内部存储其外部变量的引用,并能读写这些变量。
  • 相关阅读:
    js中调用ocx控件
    web.xml配置文件中<async-supported>true</async-supported>报错的解决方案
    shiro整合spring配置
    shiro中的reaml理解及实现机制
    oracle数据库安装
    关于身份认证、角色认证和权限认证的shiro-web例子
    创建maven管理的web项目
    hadoop Hive 的建表 和导入导出及索引视图
    hadoop Mapreduce组件介绍
    hadoop hive组件介绍及常用cli命令
  • 原文地址:https://www.cnblogs.com/meiyanstar/p/13091346.html
Copyright © 2011-2022 走看看