js代码在执行前会做的几件事情:

1.代码检测

2.预编译:在执行代码之前会对代码中的函数以及变量提前声明 并且做一些其他的处理

  1.函数在执行前的一瞬间,会生成一个OA(object action)对象

  2.函数的形参作为OA对象的属性名,实参作为AO对象的属性值

  3.分析var声明,变量名作为AO对象的属性名,值为undefined,如果遇到和参数同名的变量不去做任何改变

  4.分析函数声明,函数名作为AO 对象的属性名,值为函数体,如果遇到同名函数直接覆盖

接下来我们来分析这段代码:(按照预编译的四步走)  

  function fun(a){ 
  console.log(a)
  var a = 100
  console.log(a)
  }
  fun(10)

  1.在执行fun之前产生一个fun OA对象 ,

  2.函数的形参a = 10 ,存入AO对象

  3.var声明了一个a 值为undefined

  4.分析函数 这个函数里面并没有内层函数

做完以上分析之后 再来执行这个程序 执行过程中碰到变量的输出或改变值 就去OA对象中找:

  console.log(a)   此时a = 10 输出10

  a = 100              此时a=100

  console.log(a)   输出100

这是一个函数整体的执行过程,而闭包的形成就是在一个函数里面嵌套一个或多个函数,接下来我们再来分析闭包

  function a(){
    var num = 100;
    function b(){
      num ++;
      console.log(num)
    }
    return b;
  }
  var fun = a()
  fun()
  fun()

1.在a()执行前生成一个OA对象

2.没有形参

3.声明var num = undefined

3.声明函数b() 值为函数体

然后执行a() 给num复制为100,然后返回b()函数 fun=function b(){ } 接下来在执行到fun()时:

1.在fun()执行前产生一个OA对象

2.没有形参

3.没有var声明

4.没有函数声明

然后执行b()函数,此时num++,会先在b()自己的作用于内查找有没有num这个变量 如果没有沿着作用域链去查找num

找到a()中有num变量 这是对a()中的num执行++操作 所以a()中的num会发生改变 num=101

后续又执行了一次fun() 所有操作与上一个fun相同 但是此时a()中的num=101 再进行++操作后 num = 102

用图像化来表示整个程序的执行过程中OA发生的变化

*在整个程序执行过程中 最最需要注意的是 函数每执行一次都会产生一个相应的OA对象

就算是同一个函数 只要再次执行都会产生一个对应的OA活动对象

  

    

     

    

    

JavaScript--关于闭包(closure)的更多相关文章

  1. JavaScript 的闭包(closure)

    以下内容为本人的学习笔记,如需要转载,请声明原文链接微信公众号「englyf」https://www.cnblogs.com/englyf/ 对于闭包的理解,其实可以归纳为,在创建函数时,同时创建了一 ...

  2. JavaScript闭包(Closure)

    JavaScript闭包(Closure) 本文收集了多本书里对JavaScript闭包(Closure)的解释,或许会对理解闭包有一定帮助. <你不知道的JavsScript> Java ...

  3. 深入理解JavaScript闭包(closure)

    最近在网上查阅了不少javascript闭包(closure)相关的资料,写的大多是非常的学术和专业.对于初学者来说别说理解闭包了,就连文字叙述都很难看懂.撰写此文的目的就是用最通俗的文字揭开Java ...

  4. [转载]学习Javascript闭包(Closure)

    学习Javascript闭包(Closure)     源地址: http://www.ruanyifeng.com/blog/2009/08/learning_javascript_closures ...

  5. 在Javascript中闭包(Closure)

    在Javascript中闭包(Closure) 什么是闭包 “官方”的解释是:所谓“闭包”,指的是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分. ...

  6. javascript 闭包(closure)

    <script type="text/javascript">    //闭包(closure):内层函数可以引用存在于包围它的函数内的变量,即使外层函数的执行已经结束 ...

  7. javascript中的闭包closure详解

    目录 简介 函数中的函数 Closure闭包 使用闭包实现private方法 闭包的Scope Chain 闭包常见的问题 闭包性能的问题 总结 简介 闭包closure是javascript中一个非 ...

  8. 【转】深入理解JavaScript闭包闭包(closure) (closure)

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

  9. 理解Javascript 的闭包(closure)

    要理解闭包的概念先从变量的作用域说去 一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变量的作用域无非就是两种:全局变量和局部变量. Javascript语言的特殊之 ...

  10. JavaScript 进阶(四)解密闭包closure

    闭包(closure)是什么东西 我面试前端基本都会问一个问题"请描述一下闭包".相当多的应聘者的反应都是断断续续的词,“子函数”“父函数”“变量”,支支吾吾的说不清楚.我提示说如 ...

随机推荐

  1. python小白之数组索引

    索引 numpy中的数组索引形式和Python是一致的.如: np.arange(10) print x[2]  #单个元素,从前往后正向索引.注意下标是从0开始的. print x[-2]  #从后 ...

  2. RabbitMQ 3.7.X集群:从入门到精通,这一篇就够了

    RabbitMQ是流行的开源消息队列系统,本身已经具备了较强的并发处理速度及运行稳定性,然而在大规模的实际应用中,往往还需要使用集群配置来保证系统中消息通信部分的高可用性,并发处理性能及异常恢复能力. ...

  3. ISO/IEC 9899:2011 条款5——5.2.1 字符集

    5.2.1 字符集 1.两个字符集和它们相关联的依次顺序应该被定义:写在源文件中的集合(源字符集),以及在执行环境中被解释的集合(执行字符集).每个集合此外被划分为一个基本字符集,其内容由本子条款给出 ...

  4. 【集成模型】Boosting

    0 - 思想 Bagging算法思想是减少预测方差(variance),Boosting算法思想是为了减少预测偏差(bias). Boosting算法思想是将“弱学习算法”提升为“强学习算法”.一般来 ...

  5. Flutter 中使用Future消除Callback Hell

    /先分别定义各个异步任务 Future<String> login(String userName, String pwd){ ... //用户登录 }; Future<String ...

  6. 阶段5 3.微服务项目【学成在线】_day09 课程预览 Eureka Feign_10-课程详情页面静态化-课程详情模型数据查询接口

    根据课程详情页面写一个获取数据模型的接口 目录的数据来自于课程计划表 右侧是课程的图片 需要写一个接口 获取课程相关的所有信息. 所以就需要一个模型类,里面包含了基本信息.图片信息.等各种详情页面的信 ...

  7. Day4作业:蛋疼CRM系统

    先上流程图,还得27寸4K显示器,画图各种爽: ReadMe: 运行程序前的提示: 1.抱歉,你得装prettytable模块...... 2.还得抱歉,如果shell中运行,最好把字体调得小点,表格 ...

  8. MODRD 指令 读取地址是哪儿来的

    MODRD  s1  s2 n  例如: MODRD K1 H2102 K2    (台达VFDM变频器)   读取变频器的主频率及输出频率,并存放于寄存器D1050,D1051指令中s2的数据地址是 ...

  9. Edit Delete Mysql的主从复制

    参考博客 https://www.cnblogs.com/zhoujie/p/mysql1.html Mysql的主从复制至少是需要两个Mysql的服务,当然Mysql的服务是可以分布在不同的服务器上 ...

  10. Java面试 - 在Java中, 既然构造方法是一个方法,那么为什么不使用void 定义呢?

    Java程序编译器是根据代码结构来进行编译处理的,执行的时候也是根据代码结构来处理的. 如果在构造方法上使用void,那么此结构就会与普通方法的结构相同,这样编译器会认为此方法是一个 普通方法,而普通 ...