分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 教程案例

理解JS闭包的含义

发布时间:2023-09-06 02:32责任编辑:顾先生关键词:闭包

一、什么是闭包

  闭包就是通过返回一个函数来保留某段作用域的一种方法。通过返回函数把本该消失的作用域保留到这个函数中,并且外界可以通过函数访问这段作用域下的变量。

  例一:

1 function foo(){2 ????var a = "我是foo里面的a";3 }4 foo();

  这段代码执行后,其实a已经不存在了,因为foo执行完了之后foo的作用域消失了,所以作用域里面的变量不见了,被销毁了。在JS中存在自动垃圾回收,对不需要的变量或者没有使用的作用域进行定期清理。当foo执行完,函数内部的变量a没有在此作用域下任何地方再被引用,所以a变量的作用域会被JS内置垃圾收集器回收。

  那么,我们需要用某种方法来获得foo里面的a,怎么办呢?

  例二:

1 function foo(){2 ????var a = "我是foo里面的a";3 ????return a;//将变量a给return出来 4 }5 let b = foo();//此时b就获得foo里面的a了。

  此时,a是不是就获得了呢?并没有,我们得到的只是a的副本,假设我以某种方法修改了a的值,b不会发生任何变化。所以,我们并不是使用的foo内部的a。既然直接返回a不行,那么我们试试返回一个函数。

  例三:

function foo(c){ ???var num = c; ???return function A(){ ???????num++; ???????return num; ???}}var b = foo(5);//b = function Ab();//6b();//7

  是不是很奇怪,按道理每次都会返回6呀,怎么会每次叠加呢。其实不然,我们执行的是函数b(从foo返回出来的),并没有重新执行foo,所以也就不会每次给num重新赋值5。至于为什么会变成这种累加的情况呢,这是因为函数foo执行完后,其内部的的A函数里面对num有引用,所以foo的作用域以及变量a被保留在了函数A中,返回给了b。

  现在,我们就能在外界通过函数b来访问foo内部的变量num了。这就是闭包,我们通过返回一个函数打通了函数内部与外界的桥梁。

二、闭包的作用

  闭包可以解决的一个典型的问题就是循环绑定的问题,由于var声明的变量可以穿透作用域,所以如下的代码会出现问题。

  例四:

 <ul class="list"> ?????<li class="bloc">1</li> ?????<li class="bloc">2</li> ?????<li class="bloc">3</li> ?????<li class="bloc">4</li> ?????<li class="bloc">5</li> </ul> ?var ali = document.querySelectorAll(‘.wrap ul li‘) ?for(var i = 0,l = ali.length;i < l;i++){   ali[i].onclick = function(){ ???????console.log(i)  //5 5 5 5 5 ???} ?}

  执行上面代码你会发现,当你点击任意li时,都会打印出5。这不对呀,和我们想的不一样呀,按道理点击第几个 li 就会打印出相应的下标呀。这是因为,我们绑定了五次onclik事件,无论你有没有触发后面的的函数,for循环都会执行,当你点击的时候,for循环已经执行完了,i 的值早已经变成了5。var 声明的i能够穿透作用域,每次触发点击事件时,函数内部的 i 也都是5。

  那么,我们是不是应该想办法把每次循环时的 i 值保存下来呢,就好像每个点击事件都重新给一个新的 i 值。于是,通过闭包可以保存每次循环的 i 值,请看例子:

1 ?for(var i = 0,l = ali.length;i < l;i++){2 ?????ali[i].onclick = (function(j){3 ?????????return function(){4 ??????????????console.log(j)5 ?????????}6 ?????})(i)7 }

  我们通过立即执行函数后返回了一个函数的形式,把每次循环的 i 值通过传参放到了不同的函数中,每个函数都是一个独立的作用域,每个函数都有了各自的i值,互相不影响,现在就如我们期望的一样了,点击第几个li打印出第几个 li 的下标。

  

理解JS闭包的含义

原文地址:https://www.cnblogs.com/wk-ba/p/10340107.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved