`

关于闭包,自己理解的

阅读更多
其实一直没搞懂闭包啥意思,然后看jquery基础最后有个对闭包的解释,看得半懂不懂的,试试用java解释下

有内部函数的外部函数好比是java里的一个class,当然是一个特殊的类,比如不能再class里直接System.out.println(),但是可以在外部函数里alert()

下面把外部函数改为父函数,比较好理解点

内部函数就好比java里的方法

js
function outerFn(){
    function innerFn1(){
    }
    function innerFn2(){
    }
}
java
public class outerFn{
    public void innerFn1(){
    }
    public void innerFn2(){
    }
}


js里要在外部调用内部函数,两种方法,要么全局变量引用,要么父函数返回

1:全局变量引用
var global=[];
function outerFn(){
    function innerFn1(){
    }
    global.push(innerFn1);
}
执行
outerFn();//虽然是执行父函数,但是这里类似java里new了个新对象
global[0]();//类似java里调用对象里的方法

2:父函数返回
function outerFn(){
    function innerFn1(){
    }
    ...
    return {'fn1':innerFn1,'fn2':innerFn2};
}
执行
var global=outerFn();
global.fn1();
global.fn2();


java里调用方法就很简单
outerFn outer=new outerFn()
outer.innerFn1();
outer.innerFn2();


到目前为止都是很正常的,其实这时候闭包已经创建了,书上对闭包的解释是:当内部函数(innerFn1)在定义它的作用域(outerFn)的外部被引用时(global.fn1();),就创建了一个闭包.

但是当父函数创建了个变量,且由内部函数调用,然后内部函数在父函数外调用,问题就来了
js
function outerFn(){
    var outerVal=0;
    ...
}

java
public class outerFn{
    private int outerVal=0;
    ...
}

js里outerVal是局部变量,java里outerVal是一个类的全局变量

js
然后内部函数调用
var outerVal=0;
innerFn1(){
    outerVal++;
    alert(outerVal);
}
return {'fn1':innerFn1};
...

var global=outerFn();
global.fn1();//1
global.fn1();//2

java
private int outerVal=0;
public void innerFn1(){
    outerVal++;
    System.out.println(outerVal);
}

outerFn outer=new outerFn()
outer.innerFn1();//1
outer.innerFn1();//2

js中的outerVal如果没被调用就是普通的变量,当执行了方法后这个变量就会被回收

但是如果被内部变量(innerFn1)引用,并且这个内部变量又被外部引用执行(global.fn1())后,outerVal变量就成了一个类似于存在父函数(outerFn)中独有的全局变量,内存垃圾回收时不知道什么时候innerFn1还会引用,所以一直就不回收outerVal,一直放在内存里,就有点类似java中的static变量了,区别是java的static是程序启动的时候就创建了,这里的伪static变量是当闭包出现的时候才创建的。


简单来说:

父函数(outerFn)定义内部函数(innerFn1)。
没有闭包。内存正常回收

父函数(outerFn)定义内部函数(innerFn1),内部函数引用父函数的变量(outerVal)。
没有闭包。内存正常回收

内部函数(innerFn1)在父函数以外引用(global.fn1())。
闭包产生。内存正常回收(貌似不会正常回收,如果是被全局变量引用,那这个内部函数应该会常驻在内存中直到浏览器被关闭或者引用他的全局函数引用了其他值才会被回收吧)

当内部函数(innerFn1)调用了父函数(outerFn)的变量(outerVal),并且内部函数在父函数以外引用(global.fn1())。
闭包产生,并且outerVal变成类似存在于父函数中的全局变量(java中的static变量),内存不能正常回收。

有错的话请指正。

突然想到个问题,父函数的变量(outerVal)被内部函数调用,然后在父函数外引用导致不能回收内存,是因为在外部引用的变量(global)本身就是一个全局变量,就是说父函数的变量是被一个全局变量引用的,因为全局变量的作用域关系,当内存回收到这的时候自然会认为这个变量还在被引用是不能回收的,那如果我把全局变量手动赋值为null,就没有谁去引用这个父函数变量了,那这个父函数变量应该就会被回收了吧。不知道对不对。
0
0
分享到:
评论

相关推荐

    js闭包个人理解

    ### JavaScript闭包的理解 在JavaScript中,闭包(Closure)是一种非常重要的概念,它涉及到函数作用域、变量生命周期以及函数内部对外部作用域的访问等多个方面。本文将基于提供的文件内容,深入探讨JavaScript...

    闭包的理解

    通过以上分析,我们可以得出以下几点关于闭包的重要结论: 1. **保持状态**:闭包使得函数能够访问并操作其外部作用域中的变量,即使外部函数已经执行完毕。 2. **封装性**:闭包可以保护私有数据,因为外部作用域...

    自己理解的关于闭包函数

    自己理解闭包函数

    JS 闭包的理解

    在深入理解闭包之前,我们需要先了解JavaScript的作用域规则。 1. **作用域**:在JavaScript中,变量的作用域分为两种,全局作用域和局部作用域。全局变量在整个代码中都可访问,而局部变量只在其定义的函数内部...

    js闭包的理解以及作用.docx

    闭包是JavaScript中实现数据隐藏和封装的一种重要手段,对于理解和编写高效的JS代码至关重要。 1. **作用域的理解** - **全局变量**:在整个程序中都可访问的变量,它们在整个脚本的生命周期内都存在。 - **局部...

    javascript闭包的理解

    标题《JavaScript闭包的理解》涉及的知识点主要围绕JavaScript编程中的一个重要概念——闭包。闭包是一个高级且复杂的话题,它是JavaScript语言的核心特性之一,同时也是一大难点。要想熟练运用JavaScript,掌握闭包...

    深入理解javascript原型和闭包

    深入理解javascript原型和闭包(01)——一切都是对象 深入理解javascript原型和闭包(02)——函数和对象的关系

    闭包的理解1

    【闭包的理解】 闭包是编程中的一个重要概念,尤其在函数式编程和动态类型语言中广泛使用。它涉及到函数、作用域和变量持久化等核心编程概念。在本文中,我们将深入探讨闭包的含义以及它在不同场景下的应用。 首先...

    js 闭包的理解与注意事项

    js 闭包的理解与注意事项

    javaScript闭包的理解

    ### JavaScript闭包的理解 #### 一、闭包的定义与特点 闭包是JavaScript中一个非常重要的概念,它指的是一个函数能够访问并操作其外部作用域中的变量的能力。这一特性使得JavaScript具有了一些其他语言不具备的...

    js闭包理解之倒计时

    在这个“js闭包理解之倒计时”的主题中,我们将深入探讨如何利用闭包实现一个实际项目中的倒计时功能。 首先,让我们了解一下闭包的基本概念。在JavaScript中,每当函数被创建时,它都会形成一个闭包,这个闭包包含...

    JavaScript闭包深入理解.pdf

    首先,我们来理解闭包的定义。官方解释可能较为抽象,但简单来说,JavaScript中的每个函数都可以视为一个闭包,尤其是当一个函数内部定义了另一个函数,并且内部函数引用了外部函数的变量时,就形成了一个强大的闭包...

    理解_JavaScript_闭包

    本文结合 ECMA 262 规范详解了闭包的内部工作机制,让 JavaScript 编程人员对闭包的理解从“嵌套的函数”深入到“标识符解析、执行环境和作用域链”等等 JavaScript 对象背后的运行机制当中,真正领会到闭包的实质。

    C语言实现三种闭包算法(传递,自反,对称闭包)

    首先,我们需要理解这些闭包的定义: 1. **传递闭包**:在一个关系集合中,如果对于所有的元素a、b和c,只要a与b有关系且b与c有关系,那么a与c也一定有关系,这样的关系被称为传递闭包。在图论中,这相当于寻找最长...

    最符合菜鸟的闭包

    对于初学者来说,它可能显得有些抽象,但理解闭包对于提升编程技能至关重要。闭包是一种特殊的作用域,它允许函数访问并操作其外部作用域的变量,即使在外部函数执行完毕后仍然可以访问这些变量。 闭包的核心在于它...

    js闭包理解

    在JavaScript中,所有函数都有可能形成闭包,因为它们都能访问到自己定义时的上下文。 在描述中提到的"闭包的垃圾回收"是一个关键点,因为闭包可能导致内存泄漏。当一个函数引用了外部作用域的变量,即使函数已经...

    关系闭包的计算

    本实验旨在通过编程实践的方式帮助学习者深入理解关系闭包的概念,并熟练掌握Warshall算法用于计算关系的自反闭包、对称闭包以及传递闭包。 #### 关键概念解释 1. **自反闭包**:给定集合A上的关系R,如果对于集合...

    JavaScript对闭包的理解.md

    为了帮助大家快速和较好地理解JavaScript函数中的闭包,本文对JavaScript的闭包进行了分析并进行简易的代码演示,希望本文能够给有需要的人带来一点小小的帮助。

    计算NFA中ε闭包

    ### 计算NFA中的ε闭包 #### 一、NFA与ε闭包概念介绍 **非确定有限自动机(NFA)**是一种理论计算模型,它扩展了确定...理解并掌握了NFA和ε闭包的概念及其计算方法后,可以进一步应用于更复杂的自动机转换问题中。

Global site tag (gtag.js) - Google Analytics