本文介绍了Javascript闭包 - 变量范围问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在阅读Mozilla开发者网站上的关闭,我注意到他们的例子中的常见错误,他们有这样的代码:

 < p id =help>有用的评论会显示在这里< / p> 
< p>电子邮件:< input type =textid =emailname =email>< / p&
< p>名称:< input type =textid =namename =name>< / p&
< p>年龄:< input type =textid =agename =age>< / p&

  function showHelp(help){
document.getElementById('help')。innerHTML = help;
}

function setupHelp(){
var helpText = [
{'id':'email','help':'您的电子邮件地址' },
{'id':'name','help':'您的全名'},
{'id':'age','help':'您的年龄over 16)'}
];

for(var i = 0; i< helpText.length; i ++){
var item = helpText [i];
document.getElementById(item.id).onfocus = function(){
showHelp(item.help);
}
}
}

onFocus事件,代码将只显示最后一个项目的帮助,因为所有分配给onFocus事件的匿名函数在'item'变量周围有一个闭包,这是有道理的,因为在JavaScript变量中没有块范围。解决方案是使用'let item = ...',因为它具有块范围。



但是,我不知道为什么不能声明' var item'在for循环上面?然后它的作用域为setupHelp(),并且每次迭代都会为它分配一个不同的值,然后将其作为当前值捕获到... ...

item.help 被评估,循环将完整地完成。您可以使用闭包:

  for(var i = 0; i< helpText.length; i ++) {
document.getElementById(helpText [i] .id).onfocus = function(item){
return function(){showHelp(item.help);};
}(helpText [i]);
}

JavaScript没有块范围,但它有函数范围。通过创建一个闭包,我们永远捕获对 helpText [i] 的引用。


I'm reading the Mozilla developer's site on closures, and I noticed in their example for common mistakes, they had this code:

<p id="help">Helpful notes will appear here</p>
<p>E-mail: <input type="text" id="email" name="email"></p>
<p>Name: <input type="text" id="name" name="name"></p>
<p>Age: <input type="text" id="age" name="age"></p>

and

function showHelp(help) {
  document.getElementById('help').innerHTML = 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);
    }
  }
}

and they said that for the onFocus event, the code would only show help for the last item because all of the anonymous functions assigned to the onFocus event have a closure around the 'item' variable, which makes sense because in JavaScript variables do not have block scope. The solution was to use 'let item = ...' instead, for then it has block scope.

However, what I wonder is why couldn't you declare 'var item' right above the for loop? Then it has the scope of setupHelp(), and each iteration you are assigning it a different value, which would then be captured as its current value in the closure... right?

解决方案

Its because at the time item.help is evaluated, the loop would have completed in its entirety. Instead, you can do this with a closure:

for (var i = 0; i < helpText.length; i++) {
   document.getElementById(helpText[i].id).onfocus = function(item) {
           return function() {showHelp(item.help);};
         }(helpText[i]);
}

JavaScript doesn't have block scope but it does have function-scope. By creating a closure, we are capturing the reference to helpText[i] permanently.

这篇关于Javascript闭包 - 变量范围问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-22 13:27