我不明白 mdn 的闭包循环错误示例

I don't understand the example of closure for loop error from mdn

提问人:khuongduy354 提问时间:9/22/2021 最后编辑:mplungjankhuongduy354 更新时间:9/22/2021 访问量:47

问:

1.MDN示例

下面的代码片段分配了一个函数,该函数在聚焦时将帮助文本显示到每个文本字段,以下是指向 JsFiddle 的链接: https://jsfiddle.net/v7gjv/8164/

function showHelp(help) {
          document.getElementById('help').textContent = help;
        }
        
        function setupHelp() {
          var helpText = [
              {'id': 'email', 'help': 'Your e-mail address'},
              {'id': 'name', 'help': 'Your full name'},
              {'id': 'age', 'help': 'Your age (you must be over 16)'}
            ];
        
          for (var i = 0; i < helpText.length; i++) {
            var item = helpText[i];
            document.getElementById(item.id).onfocus = function() {
              showHelp(item.help);
            }
          }
        }
        
        setupHelp();

但它只会显示最后一个帮助文本,无论三个输入中的哪一个是重点。MDN 表示分配给所有三个输入的函数是一个闭包,因此当循环结束时,它们共享对变量 helpText 的相同引用,i=2,因此所有三个输入都引用了 helpText 中的最后一项。

2.My 测试

我不明白的部分是为什么所有三个输入都对同一个变量项具有相同的引用 我做了这样的测试

(function() {
  function closure() {
    var i = 0;
    return {
      display: function() {
        console.log(i);
      },
      add: function() {
        i += 1;
      }
    }
  }

  var a = closure();
  var b = closure();

  a.add();
  a.display(); //return 1
  b.display(); //return 0 
})()

3.My 想法和问题

从测试中,a 和 b 具有不同的 i 变量,a 的 i 发生了变化,但 b 保持不变。 但是在 for 循环中,所有输入都指向同一个变量,因此 for 循环更改值 i 导致所有输入都指向 helpText 中的最后一项

所以我的问题是为什么它们指向相同的变量,但在我的测试中 a,b 没有。

JavaScript 循环 闭包

评论

0赞 Felix Kling 9/22/2021
“但在我的测试中,A,B没有”因为是在函数内部定义的,但在 MDN 示例中,是在事件处理程序外部定义的。iitem
0赞 khuongduy354 9/22/2021
我真的不明白,我理解 onfocus 是元素属性之一 {...,onfocus:function(){}} 对吗?
0赞 Felix Kling 9/23/2021
是的,该函数已分配给属性,但这并不重要。重要的是:该函数访问一个自由变量(一个本身未定义的变量),并在循环终止调用该函数。如果将声明移到函数之外,则会实现相同的行为。var i = 0;closure

答:

0赞 Drago96 9/22/2021 #1

在示例中,您将在方法中声明变量。第二次调用时,将在该特定函数执行的范围内创建一个新变量,并将返回的对象绑定到该变量。iclosureclosurei

尝试将变量声明移到函数之外,你会看到结果与 MDN 示例相同。closure

评论

0赞 khuongduy354 9/22/2021
现在我想到,函数访问全局变量是一个非常基本的功能,只是其他语言不能像 javascript 那样分配函数
0赞 Felix Kling 9/23/2021
@khuongduy354:实际上在很多语言中,函数都是第一类对象。但即使在这些语言中,闭包的工作方式也可能不同。