js 闭包深入理解与实例分析


Posted in Javascript onMarch 19, 2020

本文实例讲述了js 闭包。分享给大家供大家参考,具体如下:

1.什么是闭包

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

创建闭包:在一个函数内部创建另一个函数

基本特点 在返回的匿名函数中 可以调用外部函数的变量 如下例中所示 内部函数(匿名函数) 可以访问外部函数的变量num 形式如a[num] 原因是匿名函数作用域链中包括外部函数test1的作用域

闭包有权访问包含函数内部的所有变量 如下面的 外部函数定义变量d 在闭包中可以直接访问到d (var dd=d)

function test1(num){
     var d;

    return function(a,b){
      var d1=a[num],d2=b[num];
      var dd=d;
 }

  }

实例参考 此时点击产品1 到 产品4 结果都是5 点击匿名函数的作用域链中包括外部函数init的活动对象 都是引用的同一个变量i 都是5 。解决办法 返回的匿名函数 通过立即执行函数 把参数i传给匿名函数

<!DOCTYPE HTML>
<html>
<head>
  <meta charset="utf-8" />
  <title>闭包演示</title>
  <style type="text/css">
    p {background:gold;}
  </style>
  <script type="text/javascript">
    function init() {
      var pAry = document.getElementsByTagName("p");
      for( var i=0; i<pAry.length; i++ ) {
        pAry[i].onclick = function() {
          alert(i);
        }
      }
    }
   
  </script>
</head>
<body onload="init();">
<p>产品 0</p>
<p>产品 1</p>
<p>产品 2</p>
<p>产品 3</p>
<p>产品 4</p>
</body>
</html>

 弹出结果都是5截图 

js 闭包深入理解与实例分析

解决办法:立即执行匿名函数 参数i是循环i的值 传递给num形参 匿名函数里 在创建闭包 可以访问这个传递过来的值num 

pAry[i].onclick = function(num){//......}(i)
<!DOCTYPE HTML>
<html>
<head>
  <meta charset="utf-8" />
  <title>闭包演示</title>
  <style type="text/css">
    p {background:gold;}
  </style>
  <script type="text/javascript">
     /*修改后*/
     function init() {
     var pAry = document.getElementsByTagName("p");
     for( var i=0; i<pAry.length; i++ ) {
     pAry[i].onclick = function(num) {

     return function(){
     alert(num)
     }
     }(i)
     }
     }

  </script>
</head>
<body onload="init();">
<p>产品 0</p>
<p>产品 1</p>
<p>产品 2</p>
<p>产品 3</p>
<p>产品 4</p>
</body>
</html>

结果点击第一展示

js 闭包深入理解与实例分析

还有这样写也是可以的

function a(){
      var pAry = document.getElementsByTagName("p");
      for( var i=0; i<pAry.length; i++ ) {
        (function(num){
          pAry[num].onclick = function() {
            alert(num);
          }
        })(i)
      }
    }

1.1 闭包的原理

-1) 闭包的作用域链 包括 闭包自身的作用域(一般返回匿名函数的作用域),外部函数的作用域(包含的外部函数),全局作用域

-2)通常,函数的作用域和所有变量都会在函数执行结束后被销毁

-3)函数返回一个闭包,这个函数的作用域会一直保存在内存中直到闭包不存在为止

使用闭包可以模仿块级作用域

-1)创建闭包并立即执行这个函数 不会再内存中留下该函数的引用

-2 )结果 函数内部的所有变量都会被立即销毁

2.什么是作用域链


执行环境:定义了变量或函数有权访问其他数据,决定它们各自的行为。

变量对象:每个执行环境都有一个与之关联的变量对象。

执行环境定义的所有变量和函数都保存在变量对象中。编写代码无法访问这个对象,解析器在处理数据时会在后台使用它。

-1)全局执行环境是最外围的一个执行环境

-2)web浏览器中,全局执行环境默认是window对象,因此所有全局变量和函数都是作为window对象的属性和方法创建的

-3)某个执行环境中的所有代码执行完毕后,该环境被销毁,保存在其中的所有变量和函数定义都随之销毁  全局执行环境直到应用程序退出--例如关闭网页或浏览器时才会被销毁

-4)每个函数都有自己的执行环境

作用域链:当代码在一个执行环境中执行时,会创建变量对象 一个作用域链

作用域链用途:保证对执行环境有权访问的所有变量和函数的有序访问

标识符解析:沿着作用域链一级一级的向上搜索标识符的过程。

函数参数也被当做变量来看待,因此访问规则与执行环境中的其它变量相同。 例子:下面函数chageColor(num){} 在闭包里tempColor(a){}里可用a[num]访问

实例解析

<script type="text/javascript">
  /*全局变量*/
  var color = 'red' ;

  function changeColor(num){
    var otherColor = 'blue',
      another =color,
     chage = changeColor();


      function tempColor(a){
         var temp = otherColor,
           temp2 = color,
           temp3 = changeColor();/*这里可以访问上层执行环境otherColor another chage 和全局color*/
         var u =a[num];


      }

  }
</script>

全局 window

             |

             |-------------color 全局变量

             |------------changeColor()

                                             |

                                             |---------------otherColor(局部变量 还有两个就是调用的上层全局环境里的color变量和函数chageColor)

                                             |---------------tempColor()

                                                                               |-------------------h(变量h不能被上层执行环境调用 只能在tempColor()里调用 标识符向上搜索沿着作用域链 这个环境里可以调用外层环境和全局环境的变量)

参考:

感兴趣的朋友可以使用在线HTML/CSS/JavaScript代码运行工具:http://tools.3water.com/code/HtmlJsRun测试上述代码运行效果。

希望本文所述对大家JavaScript程序设计有所帮助。

Javascript 相关文章推荐
jquery统计复选框选中示例
Nov 05 Javascript
jQuery实现自动与手动切换的滚动新闻特效代码分享
Aug 27 Javascript
基于JavaScript将表单序列化类型的数据转化成对象的处理(允许对象中包含对象)
Dec 28 Javascript
JavaScript+CSS实现的可折叠二级菜单实例
Feb 29 Javascript
探索Vue.js component内容实现
Nov 03 Javascript
微信小程序 自定义消息提示框
Aug 06 Javascript
说说AngularJS中的$parse和$eval的用法
Sep 14 Javascript
Element-UI Table组件上添加列拖拽效果实现方法
Apr 14 Javascript
基于vue中对鼠标划过事件的处理方式详解
Aug 22 Javascript
vue 实现边输入边搜索功能的实例讲解
Sep 16 Javascript
微信小程序实现组件顶端固定或底端固定效果(不随滚动而滚动)
Apr 09 Javascript
Vue实现购物车基本功能
Nov 08 Javascript
JS一次前端面试经历记录
Mar 19 #Javascript
jQuery实现点击滚动到指定元素上的方法分析
Mar 19 #jQuery
浅析TypeScript 命名空间
Mar 19 #Javascript
JavaScript计算出两个数的差值
Mar 19 #Javascript
JavaScript利用键盘码控制div移动
Mar 19 #Javascript
js实现百度登录窗口拖拽效果
Mar 19 #Javascript
js实现随机抽奖
Mar 19 #Javascript
You might like
一个数据采集类
2007/02/14 PHP
自编函数解决pathinfo()函数处理中文问题
2014/11/03 PHP
Javascript String.replace的妙用
2009/09/08 Javascript
拖动布局之保存布局页面cookies篇
2010/10/29 Javascript
D3.js 从P元素的创建开始(显示可加载数据)
2014/10/30 Javascript
javascript将url中的参数加密解密代码
2014/11/17 Javascript
JS实现带有抽屉效果的产品类网站多级导航菜单代码
2015/09/15 Javascript
javascript中的previousSibling和nextSibling的正确用法
2015/09/16 Javascript
Java框架SSH结合Easyui控件实现省市县三级联动示例解析
2016/06/12 Javascript
JavaScript——DOM操作——Window.document对象详解
2016/07/14 Javascript
js canvas实现擦除动画
2016/07/16 Javascript
js前端解决跨域问题的8种方案(最新最全)
2016/11/18 Javascript
利用jQuery实现一个简单的表格上下翻页效果
2017/03/14 Javascript
JavaScript实现弹出广告功能
2017/03/30 Javascript
Kotlin学习第一步 kotlin语法特性
2017/05/25 Javascript
基于jQuery的$.getScript方法去加载javaScript文档解析
2017/11/08 jQuery
node.js通过axios实现网络请求的方法
2018/03/05 Javascript
Java设计中的Builder模式的介绍
2018/03/22 Javascript
JavaScript实现图片放大镜效果
2019/06/27 Javascript
使用VUE实现在table中文字信息超过5个隐藏鼠标移到时弹窗显示全部
2019/09/16 Javascript
Vue中正确使用Element-UI组件的方法实例
2020/10/13 Javascript
JS页面动态绘图工具SVG,Canvas,VML介简介
2020/10/16 Javascript
python使用pil进行图像处理(等比例压缩、裁剪)实例代码
2017/12/11 Python
python3基于OpenCV实现证件照背景替换
2018/07/18 Python
python使用response.read()接收json数据的实例
2018/12/19 Python
python 应用之Pycharm 新建模板默认添加编码格式-作者-时间等信息【推荐】
2019/06/17 Python
python and or用法详解
2019/06/26 Python
python自带tkinter库实现棋盘覆盖图形界面
2019/07/17 Python
详解Django 时间与时区设置问题
2019/07/23 Python
Python依赖包整体迁移方法详解
2019/08/15 Python
python3使用GUI统计代码量
2019/09/18 Python
Python实现爬取网页中动态加载的数据
2020/08/17 Python
奢华时尚的创新平台:Baltini
2020/10/03 全球购物
销售行政专员岗位职责
2014/06/10 职场文书
2016年小学“公民道德宣传日”活动总结
2016/04/01 职场文书
Python编程编写完善的命令行工具
2021/09/15 Python