var f = function( ) {
    var x = 1
    function fo() {
      console.log( x++ )
    }
      return fo
  }
  var fn = f()
  fn()              //  1
  fn()              //  2
 
  以上代码实现了一个简单的闭包,每次执行 fn 其内部变量 x 都会实现自增。
  
  闭包用一种巧妙的方式将原本互不敢干的作用域联合了起来,我在之前的文章 JavaScript之引用函数调用与直接调用的区别  说到作用域只有在代码块执行的时候才会产生,还有一点没有提到:作用域所占的内存是如何回收的,以及何时释放。
 
  闭包一直饱受诟病,下面具体为大家分析下我的观点:
  
  事实上,函数体包裹的每块代码在每次执行都会新产生一个作用域,然后在函数体执行完后被释放,我们平时在执行这一个过程的时候常常忽略了这样一个事实,所以在接触到闭包这些概念的时候短时间会无法接受。当然,如果你琢磨透了的话,并没有什么难理解的,比如函数体内定义了一个变量 x = 1,每次你调用这个函数,在其内部所引用的 x 值都是1,这意味着这个变量在上次函数体被执行完后就释放了,一个独立的作用域被执行完后就会被销毁。
 
  搞明白了上面这点,也就不难理解上面的代码,如果将函数体从一个函数内发送出去,那么就意味这此函数的作用域发射到了其上级作用域内,即两个作用域联合了起来,融合到一起了,这时候JavaScript再想销毁这个作用域就会连同 window 这个作用域一起销毁,显然它不会这么干,于是,此例中函数 fo 的作用域,也即 f 所代表的函数体(作用域)被留存了下来。
 
   再引申开来,如果 f 这个函数体再执行一次会怎样呢?这时候一个新的函数体又被执行了,一个新的作用域产生又汇入了父级作用域,如果你想销毁这个作用域,又是不可能的。以上面这个例子来说,就有两个值为 1 的变量 x 进入了全局作用域,全局作用域不得不分配两个不同的隐式的变量指向这两个 x ,用行话来说,就是产生了全局污染。 
 
  var f = function( ) {
    var x = 1
    function fo() {
      console.log( x++ )
    }
    fo.alter=function ( n ) {
    x = n
    }
      return fo
  }
  var fn = f()
  fn()              //  1
  fn()              //  2
  fn.alter( 10 ) 
  fn()      //   10
 
  为了给这个函数开一个后门,使得变量 x 可以更改,给函数对象 f 增加一个 alter 的方法。
  关键点在于,此方法也是在 f 的函数体内部定义的,意味着调用也会在此作用域执行,因此更改变量 x 的值也就顺利成章了。
 

JavaScript之更改闭包内的变量值的更多相关文章

  1. SSIS - 4.使用表达式任务和脚本任务实现更改变量和输出变量值

    一.脚本任务 脚本任务是SSIS包中功能很强大的组件,尤其当内置的任务无法实现我们需要的功能的时候,我们都可以使用脚本任务来实现.脚本任务使用VSTA(Microsoft Visual Studio ...

  2. JavaScript交换两个变量值的七种解决方案

    前言 这篇文章总结了七种办法来交换a和b的变量值 1 2 var a = 123; var b = 456; 交换变量值方案一 最最最简单的办法就是使用一个临时变量了,不过使用临时变量的方法实在是太l ...

  3. C#webbrowser控件技巧(取得javascript变量值,禁止显示脚本错误)

    C#中的webbrowser控件比较好用. 下面本人搜索整理的几个小技巧. 1. 从C#中取得javascript的变量值. using mshtml;using System.Reflection; ...

  4. 理解JavaScript变量值

    JavaScript变量可能包含两种不同数据类型的值:基本类型值和引用类型值.基本类型值指的是简单的数据段,而引用类型值是指那些可能由多个值构成的对象. 在将一个值赋给变量时,解析器必须确定这个值是基 ...

  5. JavaScript高级程序设计(复制变量值、传递参数)

    复制变量值 一个变量向另一个变量复制基本类型值和引用类型值时,是存在不同的. 一个变量向另一个变量复制基本类型的值,会在变量的对象上创建一个新值,然后把该值复制到为新变量分配的位置上. var num ...

  6. JavaScript判断变量值简单的方法

    今天在看一个动态web表单设计器的时候发现项目中的 一个写法 function sum_total(v){ if (!v) { v= 0; } } !v  这是什么写法?不过可以肯定的是,这是一种判断 ...

  7. 闭包内的微观世界和js垃圾回收机制

    一.什么是闭包? 官方”的解释是:闭包是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分.相信很少有人能直接看懂这句话,因为他描述的太学术.其实这句话 ...

  8. 全面理解JavaScript中的闭包的含义及用法

    1.什么是闭包 闭包:闭包就是能够读取其他函数内部变量的函数;闭包简单理解成“定义在一个函数内部的函数”. 闭包的形式:即内部函数能够使用它所在级别的外部函数的参数,属性或者内部函数等,并且能在包含它 ...

  9. Javascript 中的闭包和引用

    Javascript 中一个最重要的特性就是闭包的使用.因为闭包的使用,当前作用域总可以访问外部的作用域.因为Javascript 没有块级作用域,只有函数作用域,所以闭包的使用与函数是紧密相关的. ...

随机推荐

  1. 使用后台的limit 控制每页的容量

    和上一个不使用limit的不同,如果不使用后台的限制,那么就必须自己定义一个计算属性,并且v-for这个计算的数组,而如果要用到后台的限制,那么就不需要自己计算,v-for的直接就是后台获取的数组 1 ...

  2. mysql的报错

    这个错误是因为mysql的进程错误关闭导致的,我们需要把/var/lib/mysql/mysql.sock文件删除或者改名,之后再重启就ok

  3. docker 下安装gitlab

    1.找到docker镜像 docker search gitlab 2.下载gitlab镜像 docker pull  gitlab/gitlab-ce/ 3.通常会将 GitLab 的配置 (etc ...

  4. 详解Python的作用域和命名空间

    最近在学习Python,不得不说,Python真的是一门很好用的语言.但是学习的过程中关于变量作用域(scope)的命名空间(namespace)的问题真的把我给搞懵了.在查阅了相关资料之后,觉得自己 ...

  5. 团队服务器搭建(搭建php环境和安装在线mysql管理工具phpmyadmin)

    1.本人良心推荐阿里云,因为他对学生来说优惠很多,比如说9.9/月的云主机,所以这里演示阿里云ubuntu系统,系统可以自己安装的 2.来到阿里云官网https://www.aliyun.com,免费 ...

  6. Java 平时作业六

    编写一个 Java 应用程序,使用 Java 的输入输出流技术将 Input.txt 的内容(Input.txt 为文本 文件)逐行读出, 每读出一行就顺序为其添加行号(从 1 开始,逐行递增),并写 ...

  7. django之CSRF

    在POST请求到达views之前,csrf帮我们进行一层验证 <!DOCTYPE html> <html lang="en"> <head> & ...

  8. 2D 加速图形界面开发源代码亲写 想买来学习得加qq 313244484 20万当前代码,完整400万包写完

    #include "StdAfx.h" #include "GUIFrame.h" #include <stdlib.h> #include < ...

  9. YYY0.1YYY

    XXX0.2XXXZZZ目前提供免费下载和自动更新功能,由于自己的时间有限,就我一个开发,后期持续更新在线听歌.mp4转mp3.高音质下载.全球dj网站免费下载功能!ZZZ

  10. APP在线课程设计

    VR在线课程是我们的主打产品,分为“人工智能鱼”.“海洋史”.“濒危海洋动物保护”.“生物进化”.“海洋知识科普”和“海洋法律”等六大主题,其中“人工智能鱼”为主打特色课程,每个主题也设置了不同难度系 ...