• js闭包深入理解(Closure)


    闭包的概念

    • 闭包是指有权访问另一个函数作用域中的变量的函数
    • 闭包是基于词法作用域书写代码时所产生的必然结果。
    • 函数对象可以通过作用域关联起来,函数体内的变量都可以保存在函数作用域内,这在计算机科学文献中称为“闭包”,所有的javascirpt函数都是闭包
    • 函数可以通过作用域链相互关联起来,函数内部的变量可以保存在其他函数作用域内,这种特性在计算机科学文献中称为闭包
    • 闭包不是一个函数,它是一种机制,用于访问自由变量

    优点

    • 不会造成全局变量的污染;
    • 可以在函数的外部访问到函数内部的局部变量(实现所谓的变量‘公有化’)。
    • 让这些变量始终保存在内存中,不会随着函数的结束而自动销毁。

    缺点

    • 闭包导致作用域链的不释放,会造成内存溢出,所以就会占用内存空间, IE容易造成内存泄露

    解决方法——使用完变量后,手动将它赋值为null

    • 闭包可能在父函数外部,改变父函数内部变量的值。
    • 由于闭包涉及跨作用域的访问,所以会导致性能损失。

    解决方法——通过把跨作用域变量存储在局部变量中,然后直接访问局部变量,来减轻对执行速度的影响

    代码片段一:

    1. <p>1p>
    2. <p>2p>
    3. <p>3p>
    1. var ps = document.querySelectorAll('p');
    2. for (var i = 0; i < ps.length; i++) {
    3. ps[i].onclick = function () {
    4. console.log(i);
    5. }
    6. }
    7. console.log(i); //3

       

    这是因为for循环已经加载完毕,可以看到每个p标签都有点击事件,而onclick是点击之后才执行的,属于同步和异步问题。当我们点击的时候,for循环已经完成,所以i的值恒为3。产生这样的问题在于这个i的值在初始化完成的时候就已经是3了

    原因

    1. 函数作用域 function{ },块级作用域 {}。
    2. 一定要有 function 关键字,才会有函数作用域。
    3. js里面 var声明的变量只有函数作用域,没有块级作用域。(也就是说,函数可以隔离变量,for不能隔离变量)。
    4. 因此,可在全局(外部)通过console.log看到 i 的值。

    解决方案

    1.let/const 块级作用域(推荐)

    1. var ps = document.querySelectorAll('p');
    2. for (let i = 0; i < ps.length; i++) {
    3. ps[i].onclick = function () {
    4. console.log(i);
    5. }
    6. }
    7. console.log(i);

     2.闭包:用立即执行的匿名函数把它包装起来,这样子做的话,log(i)的值就取自闭包环境中的i

    1. for (var i = 0; i < ps.length; i++) {
    2. (function (i) {
    3. ps[i].onclick = function () {
    4. console.log(i);
    5. }
    6. })(i);
    7. }

    3.添加自定义属性 

    1. for (var i = 0; i < ps.length; i++) {
    2. //自定义属性标签
    3. ps[i].index = i;
    4. ps[i].onclick = function () {
    5. console.log(this.index);
    6. }
    7. }

  • 相关阅读:
    【技能树笔记】网络篇——练习题解析(二)
    【24种设计模式】工厂模式(Factory Pattern)
    Kubernetes—资源管理
    华为eNSP配置专题-浮动路由及BFD的配置
    聚焦AI丨车企如何用AI服务争夺市场话语权
    典型海洋环境观测数据产品应用现状及对我国的启示
    Stackelberg博弈数值仿真,下面的MATLAB代码问题出在哪里呢?
    网络安全(黑客)自学
    RK3588平台开发系列讲解(显示篇)MIPI DSI协议介绍之分层
    Flutter flutter.minSdkVersion的实际文件位置
  • 原文地址:https://blog.csdn.net/qq_55172460/article/details/126771949