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

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

手机验证码登录
找回密码返回
邮箱找回 手机找回
注册账号返回
其他登录方式
分享
  • 收藏
    X
    关于 js 闭包(stale closure)问题的疑惑?
    46
    0

    网上看到如下两段代码:

    function createIncrement(i) {
      let value = 0;
      function increment() {
        value += i;
        console.log(value);
        const message = `Current value is ${value}`;
        return function logValue() {
          console.log(message);
        };
      }
      
      return increment;
    }
    
    const inc = createIncrement(1);
    const log = inc(); // 1
    inc();             // 2
    inc();             // 3
    // Does not work!
    log();             // "Current value is 1"
    function createIncrementFixed(i) {
      let value = 0;
      function increment() {
        value += i;
        console.log(value);
        return function logValue() {
          const message = `Current value is ${value}`;
          console.log(message);
        };
      }
      
      return increment;
    }
    
    const inc = createIncrementFixed(1);
    const log = inc(); // 1
    inc();             // 2
    inc();             // 3
    // Works!
    log();             // "Current value is 3"
    

    第二段代码与第一段代码的唯一区别仅仅在于, 将message变量移入了 logValue()函数中, 似乎就能"正确"读取到value的值

    两端代码均存在嵌套的闭包, 我个人分析的时候比较困惑, 个人理解为: value由于inc()的调用应该是不断变化的, 而由于存在最顶端的createIncrement()/createIncrementFixed()这个函数造成的闭包, 所读取的 value 值应该总是最新的即为 3? 但是似乎和实际结果有些不太符合, 不知道哪里理解错了, 恳请知道的前辈能详细分析一下? 不胜感激!

    0
    打赏
    收藏
    点击回答
    您的回答被采纳后将获得:提问者悬赏的 10 元积分
        全部回答
    • 0
    • numb.(麻木) 普通会员 1楼

      闭包(stale closure)是指在函数执行完成后仍然可以访问其内部变量的函数。如果一个函数没有返回任何值,那么它的内部变量就不会被垃圾收集器回收。这会导致一些问题,特别是当这些内部变量被用作闭包的参数时。

      在JavaScript中,闭包主要有以下几种情况:

      1. 一个函数内部定义了另一个函数,这两个函数形成了闭包。例如,function outer() { var inner = function() { console.log('outer'); } }(); outer();在这个例子中,inner函数形成了闭包,因为outer函数调用inner函数。

      2. 使用this关键字时,闭包会导致问题。例如,function outer() { var inner = function() { console.log('outer'); } }(); var obj = outer(); obj.bind({ outer: outer });在这个例子中,outer函数形成了闭包,但是bind方法将outer对象作为参数传递给了inner函数,所以outer函数仍然可以访问inner函数的内部变量。

      解决闭包问题的方法有很多,例如,可以使用let关键字来声明变量,而不是使用var关键字;可以使用const关键字来声明常量,而不是使用let关键字;可以使用const关键字来声明常量,而不是使用var关键字。此外,还可以使用function声明函数,而不是使用function声明变量,以避免letconst关键字的使用。

      总的来说,闭包是一种非常有用的编程技巧,但是使用时需要小心,以避免出现不必要的问题。

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