前端面试必问——JS中的闭包是什么?

一、什么是闭包?

先说概念:

闭包是指有权访问另一个函数作用域中变量的函数。

创建闭包的最常用的方式就是在一个函数内创建另一个函数,通过另一个函数访问这个函数的局部变量,利用闭包可以突破作用链域,将函数内部的变量和方法传递到外部。

 

二、关于闭包概念的理解

从概念中可以看出,要形成闭包有2个不可或缺的关键因素,分别是:

      ①1个函数   ②函数内部可以访问的变量

比如:

var num = 665;
function sayAlert(){
    alert(num);
}

(在上述例子中,num就是1个变量,而sayAlert则是一个函数,在该函数中可以访问num这个变量。)

 

紧接着把这几句代码放到一个立即执行函数中,再return该函数,如下所示:

function say666() {
   var num = 665;
   function sayAlert() {
       alert(num);
   }
   num++;
   return sayAlert;
}

var sayAlert = say666();
sayAlert();  //执行结果为弹出666

在上述例子中,sayAlert函数和num变量就形成了闭包。

可以看出有两个问题:

一、为什么需要函数嵌套函数?

函数嵌套函数是为了让变量成为局部变量,比如在上述例子中num就成为了局部变量,如果不嵌套直接写在外面就成为了全局变量。

所以,函数套函数就是为了制造出一个局部变量。

二、为什么需要return函数?

return函数就是为了让这个函数可以被使用,在上述例子中return sayAlert就是为了让这个函数在外部可以被使用。

 

解决了上述两个问题后,又有一个问题出现了:

为什么要让变量成为局部变量呢?

我想这个问题有好几个答案,首先是局部变量可以一直被保存在内存中,不会被垃圾回收机制回收。还有就是可以通过闭包来隐藏一个变量,比如在上述例子中我们也完全可以让num成为一个全局变量,但是我又不想让num这个变量的值被任何人任意更改(不想让别人直接访问到这个变量),所以我们可以让它成为局部变量,并且暴露一个函数,让他人可以间接访问。

三、分享一个闭包使用案例

最后给大家分享一个闭包的使用案例,使用闭包让 4个li节点的onclick事件都能正确的弹出当前被点击的li索引

<ul>
        <li>index =0</li>
        <li>index =1</li>
        <li>index =2</li>
        <li>index =3</li>
</ul>
<script>
    var nodes=document.getElementsByTagName("li");
    for(var i=0;i<nodes.length;i++){
       nodes[i].οnclick=(function(i){
            return function(){
            console.log(i)
            }
         })(i)
     }

</script>

在上述例子中,return后的函数和变量i就形成了闭包,如果不使用闭包直接打印的话,那么不管点击哪个li打印出来的值都是4。

大家可以自行尝试。


有任何问题欢迎在留言区指出和讨论(✿◕‿◕✿)

原创文章 3 获赞 12 访问量 1155

猜你喜欢

转载自blog.csdn.net/cuckooii/article/details/106141995
今日推荐