对闭包的理解

理解Python闭包概念 其实问题的关键就在于在返回闭包列表fs之前for循环的变量的值已经发生改变了,而且这个改变会影响到所有引用它的内部定义的函数。运行的结果也说明了闭包函数中引用的父函数中local variable既不具有C++中的全局变量的性质也没有static变量的行为。函数my_func一旦返回,那么内部定义的函数func便是一个闭包,其中引用的变量j成为一个只和具体闭包相关的自由变量。应该怎么正确的理解呢?C++中有static关键字,函数中的static关键字定义的变量独立于函数之外,而且会保留函数中值的变化。 阅读详情

原文地址:http://www.ruanyifeng.com/blog/2009/08/learning_javascript_closures.html

闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现。

下面就是我的学习笔记,对于Javascript初学者应该是很有用的。

一、变量的作用域

要理解闭包,首先必须理解Javascript特殊的变量作用域。

变量的作用域无非就是两种:全局变量和局部变量。

Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量。

  var n=999;

  function f1(){
    alert(n);
  }

  f1(); // 999

另一方面,在函数外部自然无法读取函数内的局部变量。

  function f1(){
    var n=999;
  }

  alert(n); // error

这里有一个地方需要注意,函数内部声明变量的时候,一定要使用var命令。如果不用的话,你实际上声明了一个全局变量!

  function f1(){
    n=999;
  }

  f1();

  alert(n); // 999

二、如何从外部读取局部变量?

出于种种原因,我们有时候需要得到函数内的局部变量。但是,前面已经说过了,正常情况下,这是办不到的,只有通过变通方法才能实现。

那就是在函数的内部,再定义一个函数。

  function f1(){

    var n=999;

    function f2(){
      alert(n); // 999
    }

  }

在上面的代码中,函数f2就被包括在函数f1内部,这时f1内部的所有局部变量,对f2都是可见的。但是反过来就不行,f2内部的局部变量,对f1就是不可见的。这就是Javascript语言特有的"链式作用域"结构(chain scope),子对象会一级一级地向上寻找所有父对象的变量。所以,父对象的所有变量,对子对象都是可见的,反之则不成立。

既然f2可以读取f1中的局部变量,那么只要把f2作为返回值,我们不就可以在f1外部读取它的内部变量了吗!

  function f1(){

    var n=999;

    function f2(){
      alert(n); 
    }

    return f2;

  }

  var result=f1();

  result(); // 999

三、闭包的概念

上一节代码中的f2函数,就是闭包。

各种专业文献上的"闭包"(closure)定义非常抽象,很难看懂。我的理解是,闭包就是能够读取其他函数内部变量的函数。

由于在Javascript语言中,只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成"定义在一个函数内部的函数"。

所以,在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。

四、闭包的用途

闭包可以用在许多地方。它的最大用处有两个,一个是前面提到的可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中。

怎么来理解这句话呢?请看下面的代码。

  function f1(){

    var n=999;

    nAdd=function(){n+=1}

    function f2(){
      alert(n);
    }

    return f2;

  }

  var result=f1();

  result(); // 999

  nAdd();

  result(); // 1000

在这段代码中,result实际上就是闭包f2函数。它一共运行了两次,第一次的值是999,第二次的值是1000。这证明了,函数f1中的局部变量n一直保存在内存中,并没有在f1调用后被自动清除。

为什么会这样呢?原因就在于f1是f2的父函数,而f2被赋给了一个全局变量,这导致f2始终在内存中,而f2的存在依赖于f1,因此f1也始终在内存中,不会在调用结束后,被垃圾回收机制(garbage collection)回收。

这段代码中另一个值得注意的地方,就是"nAdd=function(){n+=1}"这一行,首先在nAdd前面没有使用var关键字,因此nAdd是一个全局变量,而不是局部变量。其次,nAdd的值是一个匿名函数(anonymous function),而这个匿名函数本身也是一个闭包,所以nAdd相当于是一个setter,可以在函数外部对函数内部的局部变量进行操作。

五、使用闭包的注意点

1)由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。

2)闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。

六、思考题

如果你能理解下面两段代码的运行结果,应该就算理解闭包的运行机制了。

代码片段一。

  var name = "The Window";

  var object = {
    name : "My Object",

    getNameFunc : function(){
      return function(){
        return this.name;
      };

    }

  };

  alert(object.getNameFunc()());


代码片段二。

  var name = "The Window";

  var object = {
    name : "My Object",

    getNameFunc : function(){
      var that = this;
      return function(){
        return that.name;
      };

    }

  };

  alert(object.getNameFunc()());

(完)

CH395Q以太网协处理器实战调试指南 以太网协处理器是嵌入式系统实现低成本、高国产化率百兆以太网接入的关键技术路径,其核心原理在于将MAC层与物理层功能硬件化,由主控MCU协同调度完成帧收发。相比集成协议栈的SoC,协处理器具备更高实时性与更低功耗,但对寄存器时序、PHY协同、信号完整性等底层工程能力提出严苛要求。典型技术价值体现在工业PLC、智能电表、IoT网关等对可靠性与BOM成本敏感的场景中,需兼顾SPI驱动精度、MII眼图质量及REFCLK抖动控制。本文聚焦CH395Q这一主流国产以太网协处理器,深入解析其DMA缓冲区管理、PHY复位时 阅读详情

相关推荐

基于CubeMX与lwip的STM32轻量级HTTP服务器搭建及VSCode高效开发指南

本文详细介绍了如何在STM32单片机上,利用STM32CubeMX图形化配置工具和轻量级TCP/IP协议栈lwIP,快速搭建一个轻量级HTTP服务器。通过结合VSCode的高效代码编辑能力,提供了一套从硬件连接到动态网页交互(SSI/CGI)的完整开发指南,旨在为嵌入式设备提供零成本、跨平台的Web交互界面。

weixin_29163857的博客 582

错题

//************************************ 1.对于js闭包的理解,以下说法错误的是 A 一个闭包就是当一个函数返回时,一个没有释放资源的栈区 B 闭包能够访问一个函数中的局部变量 C 闭包使用不当会造成内存泄露 D 闭包需定义在匿名函数里 正确答案: D 解析: 闭包是函数中的函数,不一定非得在匿名函数中 以下哪个关键字可以实现类的继承 A inherit B extends C public D interface 正确答案: B

DcTbnk的博客 2520

Android Qcom USB Driver学习(十三)

该系列文章总目录链接与各部分简介: Android Qcom USB Driver学习(零) Android Qcom USB Driver学习(八) Android Qcom USB Driver学习(九)deals with the USB Power Delivery resources used by one or more ports on the basis of the local device policy the basis of the local device policy.opera

Android驱动开发 2611

闭包的理解

一.什么叫闭包 闭包:闭包就是能够读取其他函数内部变量的函数。例如在javascript中,只有函数内 部的子函数才能读取局部变量,所以闭包可以理解成“定义在一个函数内部的函数“。在 本质上,闭包是将函数内部和函数外部连接起来的桥梁。 二.闭包的特点 1. 让外部访问函数内部变量变成可能 2.局部变量会常驻在内存中 3.可以避免使用全局变量,防止全局变量污染; 三.闭包的好处和坏处 好处:可以读取其他函数内部的...

weixin_67651040的博客 3237

Revit实战:从零到一,手把手教你用族(Family)搭建一个完整的水闸BIM模型

本文详细介绍了如何使用Revit的族(Family)功能从零开始构建一个完整的水闸BIM模型。通过参数化族设计,实现闸门开度调整自动关联流量计算等智能化功能,提升水利工程BIM模型的工程价值和应用效率。文章涵盖族库规划、核心构件创建、高级技巧及BIM数据深度应用,为水利工程数字化提供实用指南。

weixin_28738165的博客 262

Abaqus仿真突然中断?手把手教你解决SIGTERM/SIGINT报错(附完整命令行方案)

本文深入解析Abaqus仿真中因SIGTERM或SIGINT信号导致进程意外中断的根本原因,并提供了一套完整的命令行解决方案。通过将作业提交方式从图形界面切换到命令行,并配合关键参数设置,可以有效避免因会话空闲超时或外部干扰引发的计算中断,保障长时间仿真任务的稳定运行。

devops8pract的博客 746

闭包是什么?五分钟带你了解闭包

你可以在一个函数里面嵌套另外一个函数。嵌套(内部)函数对其容器(外部)函数是私有的。它自身也形成了一个闭包。一个闭包是一个可以自己拥有独立的环境与变量的的表达式(通常是函数,因为ES6有了块级作用域的概念)。可以先点击上面链接查看MDN对闭包的讲述。闭包是指有权访问另一个函数作用域中的变量的函数。这样闭包的作用就很明显了可以在函数的外部访问到函数内部的局部变量。让这些变量始终保存在内存中,不会随着函数的结束而自动销毁。

寒烟说的博客 3万+

使用Android GPS api 实现一个轨迹记录的小功能

引入 市场上的跑步软件已经是非常多了,如咕咚和悦跑圈还有其他,很多大厂也在涉足这个方面。而最简单的运动跑步,最近几年也因简单,不限场地,运动效果出众备受大众喜欢。 我的这篇文章的内容很多也是从网上学习其他的博客内容,外加利用android自身的提供的api实现的,希望能对有这方面需求的朋友有所帮助。 介绍 先上两张图,界面比较丑,不过一些数据基本都有了,这个图片是临时要用截取的,所以轨迹线很短,之前

尝试着去了解代码 1万+

什么是闭包?(详解闭包)

什么是闭包? 闭包的优点。 闭包的缺点。 闭包的作用。 闭包

我只是个很菜的前端 1万+

nacos3.1.0适配国产数据库

Nacos 3.1.0适配国产数据库指南 本文介绍了Nacos 3.1.0版本适配达梦数据库和人大金仓数据库的具体步骤。主要内容包括:添加达梦和人大金仓的JDBC驱动依赖,修改nacos-persistence模块的配置文件及相关Java类,以及打包和运行注意事项。文章特别指出3.1.0版本需要JDK17环境,并提供了解决常见问题的建议,如添加VM options配置和不同启动方式等。通过本文的配置指导,可以实现Nacos服务在国产数据库环境下的正常运行。

梦昼初的博客 1465

手把手教你学AI GPU的UMD驱动软件开发专栏简介

通过本专栏的学习,您将掌握UMD的核心概念、开发环境搭建、API实现、内存管理和同步技术,以及在实际AI场景中的应用。通过本专栏的学习,您将不仅掌握UMD驱动开发的核心技术,还将能够将这些技术应用到实际的AI应用场景中,为您的AI应用提供更高效的硬件加速支持。无论您是想开发自己的AI加速框架,还是希望深入理解现有AI加速库的工作原理,本专栏都将为您提供宝贵的知识和实践经验。:本专栏不仅讲解UMD驱动的核心概念,还通过精心设计的实战案例,引导您从零开始构建UMD驱动,真正掌握AI GPU驱动开发的技能。

MHD0815的博客 113

js闭包的理解

百度百科对闭包的定义闭包就是能够读取其他函数内部变量的函数。在javascript中,只有函数内部的子函数才能读取局部变量,所以闭包可以理解成“定义在一个函数内部的函数。在本质上,闭包是将函数内部和函数外部连接起来的桥梁。

z1093541823的博客 1850

使用MATLAB/Simulink搭建一个简化的无人机螺旋桨气动特性模型,并通过仿真验证其基本功能

螺旋桨概述特点:螺旋桨通过旋转产生推力,推动无人机前进或上升。关键参数直径(D):影响推力和功率消耗。螺距(P):定义了螺旋桨每转一圈理论上前进的距离。效率(η):衡量螺旋桨将机械能转化为推力的有效性。应用场景:航拍摄影、农业监测、物流配送等。仿真目标搭建一个简化的无人机螺旋桨气动特性模型,涵盖从电机输入到螺旋桨输出推力的过程。分析不同条件下的系统响应特性(如推力、功率消耗),并探讨优化螺旋桨设计的方法。定义螺旋桨的一些基本物理参数,如直径、螺距、推力系数、功率系数等。使用Constant。

xiaoheshang_123的博客 428

对JavaScript中闭包的理解

之前对于闭包这个概念的理解都是模糊的,只是单纯的知道闭包的作用: 1. 可以在函数的外部访问到函数内部的局部变量。 2. 让这些变量始终保存在内存中,不会随着函数的结束而自动销毁。  而这几天通过各种资料和博客的学习,自认对闭包的概念和原理有了一定的了解,所以来分享一下我的心得。如果文中有什么不当之处,请多多谅解,并给与指正。谢谢!什么是闭包?在维基百科中的描述是: 在计算机科学中,闭包(英

王宜明的个人博客 6797

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

谈谈对闭包的理解

createComparitionFunction()的活动对象并不能在它执行完毕后销毁,因为匿名函数的作用域链中仍然有对它的引用,因为匿名函数的作用域链中仍然有对他的引用。在createComparitionFunction()执行完毕之后,其上下文执行的作用域链就会销毁,但是它的活动对象仍然会保留在内存之中,直到匿名函数被销毁。是最外层的上下文,在浏览器中,全局上下文就是我们常说的window对象,因此通过var定义的全局变量和函数都会成为window对象的属性和方法。每个函数调用都有自己的上下文。

m0_67457135的博客 1176

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

什么是闭包,对闭包的理解,闭包的用途及优缺点

什么是闭包,对闭包的理解,闭包的用途、优缺点及注意事项

weixin_48644617的博客 3万+

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

如何理解闭包

摘要 本文介绍了闭包的定义,作用,及常见的理解中的误区,并没有引入其他的专业词汇。 定义 闭包对应的英文是closure,下边的定义是来自MDN。 A closure is the combination of a function bundled together (enclosed) with references to its surrounding state (the lexical environment). In other words, a closure gives you access

凡友福老师的博客 330

关于对闭包的理解以及实例

闭包,在面试时经常被问到,也看了很多文章,书籍,但是对于闭包的理解还是停留在“在一个函数内创建另一个函数,以此可以访问使用函数中的变量”,在这总结一下加深理解。 首先,理解闭包得先了解作用域链。 1、执行环境及作用域 ...

qq_35423431的博客 306

JavaScript 什么是闭包,对闭包的理解

闭包指的是那些引用了另一个函数作用域中变量的函数,通常是在嵌套函数中实现的。比如,下面是之前展示的createComparisonFunction()函数,注 意其中加粗的代码:这里加粗的代码位于内部函数(匿名函数)中,其中引用了外部函数的变量。在这个内部函数被返回并在其他地方被使用后,它仍然引用着那个变量。这是因为内部函数的作用域链包含 createComparisonFunction()函数的作用域。要理解为什么会这样,可以想想第一次调用这个函数 时会发生什么。

m0_61362703的博客 573

关于闭包的理解

闭包 闭包的概念 闭包函数:声明一个在函数中的函数,叫做闭包函数 闭包:内部函数总是可以访问其所在的外部函数中声明的变量和参数,即使在其外部函数被返回了之后 闭包的特点 让外部访问函数内部成为可能 局部变量会常驻在内存中 可以避免使用全局变量,防止全局变量污染 会造成内存的泄露(有一块内存空间被长期占用,而不被释放) 闭包的创建 闭包就是可以创建一个独立的环境,每个闭包里面的环境都是独立的,互不干扰。闭包会发生内存泄漏,每次外部函数执行的时候,外部函数的引用地址不同,都会重新创建一个新的地址。但凡

这可不是一般的博客,这是王维诗里的博客 879

如何理解及使用闭包

那么闭包到底是啥? 根据MDN官方文档是定义:闭包 = 函数 + 周围状态(环境的)的引用 。所以闭包不等于是函数, 为了表述的方便,我称之为闭包结构。 先来个超简单的栗子 var name = 'lufei' function fn() { console.log(name) } fn+name 就形成了一个闭包的结构 function ff() { var name = 'lufei' return function fn() { return name } } //这.

JINGinC的博客 1348

JS中闭包的理解

什么是闭包? 闭包其实就是一个函数,什么样的函数?能够访问另一个函数作用域中变量的函数。 为什么要有闭包? 在回答这个问题之前,我先提一个假设,我们都知道在内部的函数可以访问外部函数的变量,假设现在就是有这么一个需要,需要外部环境来访问函数的内部变量,怎么办?这时就要用到闭包,这就要牵扯到闭包的实现原理,即作用域链的工作。每当函数创建时,JS底层都会在其执行环境下创建一个作用域链,这个作用域...

yanggreater的博客 219

函数闭包理解

概念 闭包函数:声明在一个函数中的函数,叫做闭包函数。 闭包:内部函数总是可以访问其所在的外部函数中声明的参数和变量,即使在其外部函数被返回(寿命终结)了之后。 特点 让外部访问函数内部变量成为可能; 局部变量会常驻在内存中; 可以避免使用全局变量,防止全局变量污染; 会造成内存泄漏(有一块内存空间被长期占用,而不被释放) 理解闭包自行代入这句话 结论:闭包找到的是同一地址中父级函数中对应变量...

weixin_43827424的博客 462

形象的理解闭包

闭包的介绍

weixin_62868784的博客 221
上一篇: Express+MySQL搭建后台开发
下一篇: 原型和原型链—Javascript继承机制的设计思想
阵雨丶
博客等级 码龄9年 126粉丝 52原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值