账号密码登录
微信安全登录
微信扫描二维码登录

登录后绑定QQ、微信即可实现信息互通

手机验证码登录
找回密码返回
邮箱找回 手机找回
注册账号返回
其他登录方式
分享
  • 收藏
    X
    闭包的一个常见的问题
    33
    0

    作用域链的这种配置机制引出了一个值得注意的副作用,即闭包只能取得包含函数中任何变量的最后一个值。别忘了闭包所保存的是整个变量对象,而不是某个特殊的变量。下面这个例子可以清晰的说明这个问题。

    function createFunction() {

    var result = new Array();
    
    for(var i = 0; i < 10; i++){
        result[i] = function() {
            return i;
        }
    }
    return result;

    }

    问题1:这是高级程序设计中的第7节的闭包。我说一下我的理解:首先result[]=function(){}是个闭包函数,在result[]这个匿名函数没被销毁之前,createFunction()对象是不会回收的,所以每个result[]函数的作用域链中保存的是提同一个createFunction()对象。所以i是同一个。所以result[1-10]都是10;

    function createFunction(){

    var result = new Array();
    
    for (var i = 0; i < 10; i++){
        result[i] = function(num) {
            return function() {
                return num;
            }
        }(i);
    }
    return result;

    }

    在重写了前面的createFunctions()函数后,每个函数就会返回各自不同的索引值,在这个版本中,我们没有直接把闭包赋值给数组,而是定义了一个匿名函数,并将立即执行该匿名函数的结果赋值给数组。这里的匿名函数哟一个参数num,也就是最终的函数要返回的值。在调用每个匿名函数时,我们传入了变量i。由于函数参数是按值传递的,所以就会把变量i的值复制给参数num,而在这个匿名函数内部,又创建并返回一个访问num的闭包,这样一来,result数组中每个函数都有自己num变量的一个副本,因此就可以返回各自不同的数值了。

    问题2:然后我看到这就有点懵逼了,书上只有这么一串文字。。单纯看上述文字感觉有些...难理解,不知可有人能通俗的解析一下,或者画张图什么的。。。

    问题3:为何不采用以下写法呢??

     function createFunction(){
            var result = new Array();
        
            for (var i = 0; i < 10; i++){
                result[i] = function(num) {
                   return num;
                }(i);
            }
            return result;
        }
    0
    打赏
    收藏
    点击回答
        全部回答
    • 0
    • 溪水残风 普通会员 1楼

      闭包的一个常见问题是如何正确地使用它们,以避免内存泄漏。

      在JavaScript中,闭包是函数和它周围函数的引用。这种引用可以用来访问函数外部的变量,即使函数已经被调用并返回。这使得闭包在函数被调用时,可以记住并返回变量的值,从而实现封装和复用。

      然而,如果闭包没有正确地使用,可能会导致内存泄漏。这是因为每次函数被调用时,都会创建一个新的闭包引用,如果函数中使用的变量没有被正确地管理,那么这些变量就会持续占用内存。

      以下是一些避免内存泄漏的方法:

      1. 将变量声明为全局变量:全局变量不会被闭包引用,因此可以避免内存泄漏。

      2. 使用闭包来封装函数的返回值:这样,函数的返回值就可以作为闭包的一部分,而不会被内存泄漏。

      3. 将函数作为参数传递:这样,函数的变量就可以作为闭包的一部分,而不会被内存泄漏。

      4. 使用闭包来封装计数器:这样,计数器的值就可以作为闭包的一部分,而不会被内存泄漏。

      5. 使用闭包来封装对象的属性:这样,对象的属性的值就可以作为闭包的一部分,而不会被内存泄漏。

      6. 使用闭包来封装对象的方法:这样,对象的方法的值就可以作为闭包的一部分,而不会被内存泄漏。

    更多回答
    扫一扫访问手机版
    • 回到顶部
    • 回到顶部