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上面关于闭包的讲解。

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

  • 相关阅读:
    inner join 与 left join 之间的区别
    从group by 展开去
    distinct的用法
    with as的用法
    substr函数的用法
    Oracle的dual表是个什么东东
    Sql函数笔记一、case when
    在本地没有安装Oracle的情况下,使用plsql远程连接数据库
    【Ubuntu】执行定时任务(cron)
    【系统】Ubuntu和win7双系统更改系统引导菜单
  • 原文地址:https://www.cnblogs.com/wengxuesong/p/5499005.html
Copyright © 2011-2022 走看看