7.2 闭包

定义: 闭包是指有权访问另一个函数作用域中的变量的函数.

理解闭包:

  • 作用域链: 当某个函数被调用时,会创建一个执行环境以及相应的作用域链. 作用域链中,外部函数的活动对象始终处于第二位,外部函数的外部函数的活动对象处于第三位.....直至作为作用域链终点的全局执行环境
  • 变量对象: 全局函数的变量对象始终存在, 而局部环境的变量对象只在函数执行的过程中存在.
  • 一般来讲, 当函数执行完毕后, 局部活动对象就会被销毁, 内存中仅保存全局作用域(全局执行环境中的变量对象)但是闭包的情况又不同
  • 在另一个函数内部定义的函数对象会将包含函数(即外部函数)的活动对象添加到它的作用域链中.
  • 对应闭包, 在外部函数执行完毕后, 其活动对象也不会被销毁, 因为匿名函数的作用域链仍然在引用这个活动对象. 即外部函数返回后, 其执行环境的作用域链会被销毁,但它的活动对象仍然会留在内存中, 直到匿名函数被销毁后, 其活动对象才会被销毁.
  • 因为闭包会携带包含它的函数的作用域, 因此会比其他函数占用更多的内存

闭包的副作用:

  • 闭包只能获取包含函数中任何变量的最后一个值. 因为闭包所保存的是整个变量对象, 而不是某个特殊的变量
  • function createFunctions(){
    var result = new Array();
    for(var i=0; i<10; i++){
    result[i] = function(){
    return i;
    };
    }
    return result;
    }

      以上这个函数会返回一个函数数组,但是其每个函数都会返回10. 因为每个函数的作用域链中都保存着createFunctions()函数的活动对象,所以它们引用的都是同一个变量i

  • 改进方法:
    function createFunctions(){
    var result = new Array();
    for( var i=0; i<10; i++){
    result[i] = function(num){
    return function(){
    return num;
    };
    }(i);
    }
    return result;
    }

      创建另一个匿名函数强制让闭包的行为符合预期.

     这样一来, result数组中的每个函数都有自己num变量的一个副本, 因此就可以返回各自不同的数值了.

《JavaScript》高级程序设计第7章 函数表达式的更多相关文章

  1. 《JavaScript高级程序设计》笔记:函数表达式(七)

    递归 function factorial(num){ if(num<=1){ return 1; }else { return num * arguments.callee(num-1); } ...

  2. 读书笔记 - js高级程序设计 - 第七章 函数表达式

      闭包 有权访问另一个函数作用域中的变量的函数 匿名函数 函数没有名字 少用闭包 由于闭包会携带包含它的函数的作用域,因此会比其它函数占用更多的内存.过度使用闭包可能会导致内存占用过多,我们建议读者 ...

  3. 《JavaScript高级程序设计》——第二章在HTML使用JavaScript

    这章讲的是JavaScript在HTML中的使用,也就是<script>元素的属性.书中详细讲了async.defer.src和type四个<script>的属性. 下面是对第 ...

  4. js高级程序设计(七)函数表达式

    定义函数的方式有两种:一种是函数声明,另一种就是函数表达式.函数声明的语法是这样的. function functionName(arg0, arg1, arg2) { //函数体 } Firefox ...

  5. JavaScript 高级程序设计 第5章引用类型 笔记

    第五章 引用类型 一.object类型 1.创建方法: 1.使用new 操作符创建 var person=new object() Person.name=”Nicholasa” Porson.age ...

  6. 读书时间《JavaScript高级程序设计》三:函数,闭包,作用域

    上一次看了第6章,面向对象.这里接着看第7章. 第7章:函数表达式 定义函数有两种方式:函数声明.函数表达式 //函数声明 function functionName(arg0,arg1,arg2){ ...

  7. JAVASCRIPT高程笔记-------第 七章 函数表达式

    7.1递归 经典递归例子 function factorial(num){ if(num <= 1){ return 1; }else{ return num * factorial(num - ...

  8. JavaScript高级程序设计第20章JSON 笔记 (学习笔记)

    第二十章 JSON 1.Json 可以表示三种类型的值: 1.简单值: 表示数值:5  表示字符串:“hello wrold”注表示字符串时必须使用双引号 2.对象: {“name”:“mi”,”ag ...

  9. JavaScript高级程序设计第14章表单脚本 (学习笔记)

    第十四章 表单脚本 1.阻止默认表单提交 1.提交表单数据 1.使用type=submit提交按钮 2.使用submit():方法 注意:当用户点击提交按钮时,会触发submit事件,从而在这里我们有 ...

随机推荐

  1. iOS - OC - 字典快速遍历

    1. [dic enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop ...

  2. 关于block元素和inline元素

    呃...这个会不会太基础了.最近在复习,所以基础知识也不能够忽略. 根据HTML 4.01 规范,其描述如下(http://www.w3.org/TR/html401/struct/global.ht ...

  3. 【转】VS2012 中文版转英文版 英文版转中文版 界面语言切换

    [1]下载VS2012的语言包,各种语言包都有,下载对应的即可. 微软官网衔接地址:vs2012 语言包  http://www.microsoft.com/zh-CN/download/detail ...

  4. 在windows系统下安装oracle 11g

     oracle 11g 安装在windows server 2012 系统下. 最近,需要配置数据库,要求在windows操作系统下,安装oracle 11g 数据库,因为以前没有安装过,所以成功后, ...

  5. redhat安装xwindow环境

    . yum groupinstall "X Window System" . yum groupinstall "GNOME Desktop Environment&qu ...

  6. Laravel - Opening Multiple Projects

    On this page: Basics Opening multiple projects Deleting a project from view Important notes Basics P ...

  7. HttpClient的几个实现类

    DefaultHttpClient最基本的HttpClient实现 org.apache.http.impl.client.DefaultHttpClient占用内存23字节 第一次初始化的时候需要2 ...

  8. URL编码转换函数:escape()、encodeURI()、encodeURIComponent()

          函数出现时间:                      escape()                                javascript 1.0           ...

  9. 3层+SVN学习笔记(1)

    public List<MemberTypeInfo> GetList() { //查询未删除的数据 string sql = "select * from memberType ...

  10. 第一个Django应用

    Django教程:http://www.liujiangblog.com/course/django/2 第一个Django应用 该应用包括以下两个部分: 一个可以让公众用户进行投票和查看投票结果的站 ...