JS中的闭包

作者: Bennt | 来源:发表于2017-08-02 10:32 被阅读39次

闭包是JS中的一个重要的概念,在模块封装,保存变量中有着重要的作用,掌握闭包在前端开发中占着非常重要的角色。在了解闭包之前我们需要了解一下JS的垃圾回收机制和作用域。

一、垃圾回收机制

我们知道前端开发中,JS中最好不要存在过多的全局变量,这样可以避免全局变量的污染,和在创建新的变量或者函数中存在冲突的情况。所以有时候我们可能会看到如下所示:

var a = 1;
var b = a;
var a = null;

即将全局中不再使用的变量赋值为null。那大家知道为什么赋值给null,为什么不赋值给undefined?

这个就牵涉到JS的垃圾回收机制了,JS中的垃圾回收机制将会每隔一段时间,按照一定的算法和规则,找出不再使用的变量对象,进行回收,提高页面的性能,而a = null正是让a失去赋值1的引用,此时a就变成不再使用的变量对象了,将会在下一次的垃圾回收中被销毁。

二、作用域

JS中存在两种作用域,全局作用域和函数作用域(第三种作用域eval因为我们平常很少用到,并且浪费计算机算力,所以我们很少使用,这里不做讨论)。

var a = 1;
function demo(){
    var b = 2;
    console.log(a);
}
demo(); //1
console.log(b);  //  b is not defined

上面函数存在两个作用域,一个是全局作用域window,一个是函数demo的作用域,按照规范是函数作用域可以访问全局变量,而全局变量是不能访问函数作用域的变量,所以在执行demo函数的时候,能够打印出1,而在打印b的时候会报错没有找到。

三、闭包
var a = 1;
function demo(){
    var b = 2;
    function c(){
        console.log(b);
    }
    a = c;
}
demo();
a();  //2

上面代码执行流程为先执行demo函数,在内存中创建函数function(){console.log(b)},变量c指向该函数,通过a=c,a也指向该函数,当demo函数执行完毕后,不再存在c变量,然后执行a(),由于a已经获得函数c的引用,所以执行结果过打印出2。

闭包经典例子:
点击li标签,打印当前标签的索引。

<ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
</ul>
<script>
    var ul = document.getElementsByTagName("ul")[0];
    var i = 0;
    var lis = ul.getElementsByTagName("li");
    var len = lis.length;
    for(;i<len;i++){
        (function(j){
            lis[i].onclick = function (){
                console.log(j);
            }
        })(i)   
    }
</script>

为什么需要使用立即执行函数(function(){})()?

在执行for循环的过程中,点击事件并没有触发,相应的函数也不会执行。如果不使用闭包保存i的话,当我们在点击li标签的时候,此时for循环已经全部执行完毕,此时i=2,无论点击任何i标签将会打印同样的结果。

使用立即执行函数的目的就是将每次for循环的i值保存在当前函数中,这样我们在每一次的点击li标签的时候就能获取当前li的索引值了。

相关文章

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

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

  • 简单的聊一下闭包

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

  • 浅谈闭包

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

  • php之闭包函数(Closure)

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

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

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

  • JS闭包

    JS闭包 闭包练习

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

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

  • 2018-01-10

    js中的闭包 一.什么是闭包 闭包官方的解释是:闭包就是能够读取其他函数内部变量的函数。由于在javascr...

  • js经典题目

    1闭包 链接:学习Javascript闭包(Closure) setTimeout在js单线程中只是放在队列中并未...

  • 前端面试题(持续补充)

    js,node.js基础: 闭包 闭包是能够读取其他函数内部变量的函数。在js中,只有函数内部的子函数可以访问内部...

网友评论

    本文标题:JS中的闭包

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