CoffeeScript 在 'for v in values' 中创建一个全局变量 'v',导致事件中的错误引用
CoffeeScript makes a global variable of `v` in `for v in values` causing wrong references at events
我有以下CoffeeScript代码:
for date of dates
Dom.section !->
Dom.div !->
Dom.text if date.attending then 'Y' else 'N'
Dom.onTap !->
Dom.text date.id
它被转换为以下JavaScript(根据 coffeescript.org(
var date;
for (date in dates) {
Dom.section(!function() {
return Dom.div(!function() {
Dom.text(date.attending ? 'Y' : 'N');
return Dom.onTap(!function() {
return Dom.text(date.id);
});
});
});
}
不要打扰代码的确切作用,因为我正在使用发生的API(一个新的对话应用程序,用户可以在CoffeeScript中制作插件(,因此,无论如何你都不会理解它。
不过我会解释一下:
-
dates
是一个长度为 10 的数组,其中包含对象。这些对象包含id
、day
、year
、attending
等键。 - 我遍历所有日期,并在屏幕上将它们呈现在所谓的"部分"中。
- 每个部分都包含多个div(为了简单起见,在上面的示例中只有一个(。
- 上面的div 包含一些文本。"Y"表示用户正在参加活动,"N"表示他不在。
- 当用户点击此div 上的 ('onTap'-event( 时,它将更新本地和共享存储(在上面的示例中,它只会添加一些文本进行调试(。
一切正常,它在正确的部分中显示正确的日期和与会者人数。因此,date
对象包含正确的数据。
问题所在
我遇到的问题是当我点击带有 onTap-event 的div 时。当我点击它时,它将始终使用渲染的最后日期。因此,假设我的日期01-12-14
到10-12-14
。我点击05-12-14
,它会在屏幕上添加 10-12-14 的 id 作为文本。经过长时间的打破和诅咒,我找到了导致这种情况的原因,但我不知道如何解决它。
请参阅 JavaScript 的第一行(seconde 代码示例(。如您所见,它正在声明一个全局变量date
。一切都呈现良好,但是当我单击某些内容时,它将引用date
,但是由于date
已在循环的最后一次迭代中更新,因此它将始终使用该id。
所以。如何确保date
每次迭代循环保持私密,并确保它在事件中使用正确的值?
注意
for k, v in dates
也不起作用,因为它也使k
全球化。因此,简单地使用dates[k].id
是行不通的。
它不是声明全局的,只是该代码的全局内容。如果它在函数中,则不会是全局函数。
这个问题与全局变量无关。这是因为闭包的工作方式。闭包具有对它们关闭的变量的持久引用,而不是创建闭包时其值的副本。因此,您为 onTap
处理程序创建的所有函数都使用相同的单个date
对象。
为了防止这种情况,给他们每个人一些自己的东西来关闭,不会改变。如果dates
是数组,请使用 forEach
。
(对于那些熟悉CoffeeScript但不熟悉Happen的人注意:->
前面的!
不是通常的!
运算符。发生扩展了CoffeeScript,使得一个函数是用!->
而不是->
来声明的,Coffeescript通常具有的隐式返回值不会生成。[感谢Erik Dolor指出这一点。
所以:
dates.forEach (date) !->
Dom.section !->
Dom.div !->
Dom.text if date.attending then 'Y' else 'N'
Dom.onTap !->
Dom.text date.id
。它变成了这个JavaScript:
dates.forEach(function(date) {
Dom.section(function() {
Dom.div(function() {
Dom.text(date.attending ? 'Y' : 'N');
Dom.onTap(function() {
Dom.text(date.id);
});
});
});
});
现在,为forEach
回调的每个迭代创建的闭包将关闭该回调迭代的参数date
,该参数不会更改。
- 全局变量和全局对象的属性之间有什么区别吗
- delete关键字在全局变量上的不同行为
- 在javascript函数中设置全局变量
- 如何将getJson的响应保存在全局变量中
- 从Javascript方法返回全局变量
- "“;变量未引用正确的对象
- AngularJS中的封装窗口全局变量
- javascript隐式全局变量
- 引用计时器JS的非全局变量
- 通过 Excel VBA 引用 Acrobat Javascript 全局变量所需的语法是什么?
- CoffeeScript 在 'for v in values' 中创建一个全局变量 'v',导致事件中的错误引用
- 通过引用传递全局变量并修改引用的变量
- 对模块中全局变量的引用
- 引用html中的jquery全局变量
- 跨多个html和全局变量引用的公共js文件
- 构造函数函数.可以't覆盖对全局变量的引用
- 需要从js文件中引用Java全局变量
- JavaScript:全局变量don'似乎不可在本地引用
- Javascript中的变量引用.通过函数引用全局变量并对其起作用
- 如何在 javascript 中通过引用将全局变量作为参数传递