zoukankan      html  css  js  c++  java
  • Js闭包

    Js闭包

    闭包:闭包是指有权访问另一函数作用域中的变量的函数
    优点:变量长期存储在内存中;无法通过其他途径访问修改,从而达到了保护变量安全的效果;
    缺点:常驻内存,增加内存使用量;使用不当会很容易造成内存泄露
    JavaScript垃圾回收机制:如果一个对象不再被引用,那么这个对象就会被回收,如果两个对象相互引用,而不再被第三方引用,那么这两个对象会被回收,上述父函数被子函数引用,子函数又被外部引用,这就是父函数不被回收的原因
    作用域链:为了保证在执行环境中有权访问的变量和方法是有序的,只能向上访问,到window终止,即作用域链向下访问是不被允许的

    <div>
        <p>第一个</p>
        <p>第二个</p>
        <p>第三个</p>
    </div>
    <script>
        let oP = document.getElementsByTagname('p')
    </script>
    

    最经典的闭包例子,点击那一个控制台输出这个元素的index
    A错误写法:

    for (let i = 0; i < oP.length; i++){
        oP[i].onclick = function (){
            console.log(i)
        }
    }
    

    原理:因为匿名函数中没有i,所以当点击文字然后进行调用其匿名函数打印的时候必须向上查找,一直找到全局里面找到了i。因为for循环执行完以后,全局的i就变成了3,那么此时打印出来的自然也是3。所以不管点击第几个打印出来的都是3
    B正确写法:

    for (let i = 0; i < oP.length; i++){
        oP[i].onclick = function (j){
            return functio () {
                console.log(j)
            }
        }(i)
    }
    

    原理:通过用自执行函数的方式我们可以把i作为参数传给自执行函数,此时的i就成了自执行函数的局部变量。自执行函数会直接执行,但不会销毁这个执行,因为里面还有一个匿名函数。执行后的局部变量i就和外界的全局变量中的i掐断联系了,也就是说传进来的i是多少,自执行函数内的i就是多少。因为还有一个匿名函数的存在,这个局部变量i是不会消失的,此时执行ruturn中的匿名函数,它自己没有i,所以会向上查找,一旦找到局部变量i那么就停止再往上查找了,所以就等于传进来的值而不是等于全局变量i
    PS:自执行函数

    (function(a){
        console.log(a)
    })(2)
    等同于
    function test(a){
        console.log(a)
    }
    test(2)
    

    理解闭包:

    for (let i = 0; i < oP.length; i++){
        oP[i].onclick = function(j){
            return function(){
                console.log(j)
                console.log(i)
            }
        }(i)
    }
    
  • 相关阅读:
    快速幂 快速乘法
    扩展欧几里得学习笔记
    求逆序数数目(树状数组+离散化)
    隐式图的遍历
    随机数生成
    推倒重来
    动态规划初步
    子集生成
    东大oj1155 等凹函数
    P1278 单词游戏
  • 原文地址:https://www.cnblogs.com/kaizhadiyishuai/p/12344901.html
Copyright © 2011-2022 走看看