JS 闭包

作者: timehorse | 来源:发表于2019-07-30 22:57 被阅读0次

闭包

mdn上定义是:函数和声明该函数的词法环境的组合。

维基定义是:闭包 词法闭包(Lexical Closure)或函数闭包(function closures),是引用了自由变量的函数。这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外

支持闭包的语言中,通常函数会是一等公民。也就是函数可以像普通变量一样使用。

相信你没有接触过的话读完只会更困惑。

我们知道JS是支持闭包的,下面看一个JS的🌰。

var scope = "global scope";
function checkscope(){
    var scope = "local scope";
    function f(){
        return scope;
    }
    return f;
}

var foo = checkscope();
foo();

该例子中:函数checkscope内仍有一个函数f,而且f内引用了一个外部变量scope,其定义在checkscope中,但使用在f中。在调用时,分了两步:第一步执行checkscope(),其执行结束后有什么结果呢?答案是scope变量并未销毁,因为f函数仍然引用了它。故第二步执行foo()才没有问题。

这就是闭包的形式。

语言对比

像上面的这种函数套函数的写法,就是闭包的形式之一。有许多语言支持闭包,比如python,lua。并不是所有语言呢都支持这样,比如c语言,我们看一下c语言的函数,假如如下:

void func1(){
    printf("http://c.biancheng.net");
    void func2(){
        printf("C语言小白变怪兽");
    }
}

上述定义是❌的,因为C语言的函数不能嵌套定义。

闭包理解

闭包允许内层函数引用父函数中的变量。注意这里说的是对外层的引用。

示例:

/**
 * <body>
 * <ul>
 *     <li>one</li>
 *     <li>two</li>
 *     <li>three</li>
 *     <li>one</li>
 * </ul>
 */

var lists = document.getElementsByTagName('li');
for(var i = 0 , len = lists.length ; i < len ; i++){
    lists[ i ].onmouseover = function(){
        alert(i);    
    };
}

这里鼠标移过每个li元素,总是弹出4。

为什么呢?

首先在匿名函数( function(){ alert(i); })内部查找是否定义了 i,结果是没有定义;因此它会向上查找,查找结果是已经定义了,并且i的值是4(循环后的i值);所以,最终每次弹出的都是4。

其中一种解决办法是:

var lists = document.getElementsByTagName('li');
for(var i = 0 , len = lists.length ; i < len ; i++){
    (function(index){
        lists[ index ].onmouseover = function(){
            alert(index);    
        };                    
    })(i);
}

内存泄漏

闭包十分容易造成浏览器的内存泄露。JS采用的是一种自动垃圾回收机制。当一个对象无用的时候,即程序中无变量引用这个对象时,就会从内存中释放掉这个变量。

循环引用

A->B->C->B :这里增加了C的某一属性引用B对象,如果这是清除A,那么B、C不会被释放,因为B和C之间产生了循环引用。

闭包非常容易创建循环引用,故有可能导致内存泄漏。

相关文章

  • php之闭包函数(Closure)

    php闭包函数(Closure) JS闭包 js和php闭包使用和区别

  • JS闭包

    JS闭包 闭包练习

  • JS闭包问题(二)

    在之前的JS闭包问题(一)文章中大概介绍了一下JS闭包,同时讲了闭包与变量之间的问题,今天我们继续聊闭包,聊聊闭包...

  • JS闭包大结局(JS闭包系列3)

    在上一篇中再谈JS闭包(JS闭包系列2),我详细的介绍了JS中的变量作用域相关的概念,结合第一节关于JS闭包(JS...

  • JS闭包入门

    最近有看到朋友的面经里提到的JS闭包的问题,就想研究研究,以下是我对JS闭包的简单理解。 到底什么是JS闭包? 定...

  • 学习JavaScript闭包和作用域笔记

    JS JavaScript闭包和作用域 闭包 JavaScript高级程序设计中对闭包的定义:闭包是指有权访问另外...

  • 再谈JS闭包(JS闭包系列2)

    这篇文章,来继续谈谈Javascript闭包的剩余问题。因为在上一篇文章中关于JS闭包(JS闭包系列1)主要简单的...

  • 简单的聊一下闭包

    js中的闭包 闭包是学习js中永远也绕不过去的一个坎,那么,今天我们就去一段简单的代码开始聊一聊闭包 什么是闭包 ...

  • 浅谈闭包

    js中的闭包 闭包是学习js中永远也绕不过去的一个坎,那么,今天我们就去一段简单的代码开始聊一聊闭包 什么是闭包 ...

  • 闭包??

    什么闭包,闭包有什么用?http://js.jirengu.com/pogadikofa/1/闭包是在某个作用域内...

网友评论

      本文标题:JS 闭包

      本文链接:https://www.haomeiwen.com/subject/udiorctx.html