js 闭包理解

起因于周三的前端面试 面试官问我闭包的问题 我信誓旦旦的说 闭包是函数和它所包含的的外部环境 其实我是这样理解的 (哪里有问题希望指出 )

    var a = 10;
            function test() {
                alert(a+1);
            }
            test();

这个只是一个函数的变量的作用域的问题 跟闭包貌似是无关了

所以我回来过了一天才开始想这个问题 下面是我的学习过程

首先我重新理解下了js中变量的作用域的问题

变量的作用域有全局变量和局部变量 js中函数内部能读取全局变量 而外部无法读取函数内部的局部变量

上面的例子就是函数内部读取全局变量的例子

而这样

    function test() {
                var n = 10;
            }
            alert(n);

会报错 n 未定义 //其实这是js中的作用域链的问题 当函数需要查询一个变量的值的时候 它先从本地的变量中找 找不到会不断的往上查找 所以 函数内部能读取全局的变量而函数外部不能读取内部的局部变量

我又了解了下js的垃圾回收机制 函数调用的时候先会为内部的变量分配内存供后面的代码操作 当函数执行完毕后这些分配了内存的变量就会被认为是没用的了 会被回收 但是会有这种情况  在函数中嵌套了另一个内部函数 这个函数可能会在外部调用并且它使用了外部函数的某些变量的话  当它被外部调用完后直接调用这个内部函数的话 这个内部函数可能无法读取它所需要的值(有可能被初始)  所以js解释器会自动将函数和它相关的变量包括父级变量打包 也就形成了闭包

 上面这段话挺不好理解 可以这样理解就是函数和它包含的外部环境

 写到这里我想举个我的例子 这次是去笔试 题目是这样的

   <ul>
            <li></li>
            <li></li>
            <li></li>
        </ul>

第一个li alert 1 第2个alert2 所以我就这样写了

function test() {
                var lis = document.getElementsByTagName("li");
                for(var i = 0;i < lis.length; i++) {
                    lis[i].onclick = function() {
                        alert(i+1);
                    }
                }
 }

结果并不是我所想象的 差别很大。。。(全是alert4)  这里就有闭包的概念 function() {alert(i+1)} 与 外部的变量构成了闭包 但是为什么结果是这样呢? 是因为刚才我们只是获得外部变量的一个引用 所以得到的只是它最后的值

如何解决呢? 我们可以让内部函数在创建的时候立即执行 并且将外部变量的变量记录下来 在调用的时候使用并且返回

这样

function test() {
                var lis = document.getElementsByTagName("li");
                var i = 0;
                for(;i < lis.length;i++) {
                    lis[i].onclick = (function(j){
                        return function() {
                            alert(j+1);
                        }
                    })(i);

                    
                }
            }

 

 

 

js 闭包理解,古老的榕树,5-wow.com

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。