zoukankan      html  css  js  c++  java
  • [Effective JavaScript 笔记] 第11条:熟练掌握闭包

    理解闭包三个基本的事实

    第一个事实:js允许你引用在当前函数以外定义的变量。

    function makeSandwich(){

          var magicIngredient=”peanut butter”;

          function make(filling){

                    return magicIngredient+’and ’+filling;

          }

          return make(‘jelly’);

    }

    makeSandwich();//”peanut butter and jelly”

    图上直接指出如下

    image

    第二个事实:即使外部函数已经返回,当前函数仍然可以引用在外部函数所定义的变量。

    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”

    还是上图标识

    image

    原理:js的函数值包含了比调用它们时执行所需要的代码还要多的信息。而且js函数值还在内部存储它们可能会引用的定义在其封闭作用域的变量。那些在其所涵盖的作用域内跟踪变量的函数被称为闭包。make函数就是一个闭包。其代码引用了两个外部变量:magicIngredient和filling。每当make被调用时,其代码都能引用到这两个变量,因为该闭包存储了这两个变量。

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

    function sandwichMaker(magicIngredient){

                function make(filling){

                       return magicIngredient+”and ”+filling;

                 }

                 return make;

    }

    var hamAnd=sandwichMaker(“ham”);

    hamAnd(“cheese”);//”ham and cheese”

    hamAnd(“mustard”);//”ham and mustard”

    var turkeyAnd=sandwichMaker(“trukey”);

    turkeyAnd(“Swiss”);//”trukey and Swiss”

    turkeyAnd(“Provolone”);//”trukey and Provolone”

    闭包是js最优雅、最有表现力的特性之一,也是许多惯用法的核心。js还提供了一种更为方便构建闭包的字面量语法--函数表达式。

    function sandwichMaker(magicIngredient){

                  return function(filling){

                         return magicIngredient+”and ”+filling;

                 }

    }

    请注意,该函数表达式是匿名的。由于只需要产生一个新值,而不需要在局部使用,所以没必要给该函数命名。

    第三个事实:闭包可以更新外部变量的值。

    实际上,闭包存储的是外部变量的引用,而不是它们的值的副本。因此任何具在访问这些外部变量的闭包,都可以进行更新。

    function box(){

           var val=undefined;

           return {

                 set:function(newVal){val=newVal},

                 get:function(){return val},

                 type:function(){return typeof val}

           }

    }

    var b=box();

    b.type();//”undefined”

    b.set(98.6);

    b.get();//98.6

    b.type();//”number”

    这个例子里产生了一个包含三个闭包的对象。这三个闭包是set,get和type属性。它们共享访问val变量。

    提示

    • 函数可以引用定义在其外部作用域的变量
    • 闭包比创建它们的函数有更长的生命周期
    • 闭包在内部存储其外部变量的引用,并能读写这些变量

    后记

    这个部分,这觉得这里讲得已经很清楚,如果想再深入去了解,可以去看高3上面关于闭包的讲解。

    里面对作用域链,执行环境,变量对象,都有详细说明。

  • 相关阅读:
    SAP OPEN UI5 Step 8: Translatable Texts
    SAP OPEN UI5 Step7 JSON Model
    SAP OPEN UI5 Step6 Modules
    SAP OPEN UI5 Step5 Controllers
    SAP OPEN UI5 Step4 Xml View
    SAP OPEN UI5 Step3 Controls
    SAP OPEN UI5 Step2 Bootstrap
    SAP OPEN UI5 Step1 环境安装和hello world
    2021php最新composer的使用攻略
    Php使用gzdeflate和ZLIB_ENCODING_DEFLATE结果gzinflate报data error
  • 原文地址:https://www.cnblogs.com/wengxuesong/p/5499005.html
Copyright © 2011-2022 走看看