Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/369.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript CoffeeScript为值中的v生成一个全局变量'v`in',从而在事件中导致错误引用_Javascript_Coffeescript_Happening - Fatal编程技术网

Javascript CoffeeScript为值中的v生成一个全局变量'v`in',从而在事件中导致错误引用

Javascript CoffeeScript为值中的v生成一个全局变量'v`in',从而在事件中导致错误引用,javascript,coffeescript,happening,Javascript,Coffeescript,Happening,我有以下咖啡脚本代码: 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) 不必担心代码到底做了什么,因为我使用

我有以下咖啡脚本代码:

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)

不必担心代码到底做了什么,因为我使用的是API of Accounting(一个新的对话应用程序,用户可以在CoffeeScript中制作插件),正因为如此,你无论如何都不会理解它

不过,我会解释:

  • 日期
    是长度为10的数组,其中包含对象。这些对象包含诸如
    id
    day
    year
    出席
    等键
  • 我循环所有日期,并在屏幕上呈现所谓的“部分”
  • 每个部分都包含几个div(为了简单起见,在上面的示例中只有一个div)
  • 上面的div包含一些文本。”当用户参加活动时为“Y”,当用户不参加活动时为“N”
  • 当用户点击此div上的('onTap'-event)时,它将更新本地和共享存储(在上面的示例中,它将只添加一些文本以进行调试)
一切正常,它在正确的部分显示了正确的日期和与会者人数。因此,
date
-对象包含正确的数据

问题 我遇到的问题是当我用onTap事件点击div时。当我点击它时,它将始终使用渲染的最后一个日期。假设我有日期
01-12-14
10-12-14
。我点击
05-12-14
,它会在屏幕上添加10-12-14的id作为文本。经过长时间的折磨和咒骂,我发现了原因,但我不知道如何解决它

请参阅JavaScript的第一行(第二个代码示例)。如您所见,它正在声明一个全局变量
date
。一切都很好,但当我单击某个对象时,它将引用
date
,但由于
date
在循环的最后一次迭代中已更新,因此它将始终使用该id

所以。如何确保
date
在每次迭代循环中保持私有,并确保它在事件中使用正确的值

对于k,日期中的v也不起作用,因为它使
k
也是全局的。因此,简单地使用日期[k].id
是行不通的。

它不是声明一个全局的,只是声明一个全局的代码。如果它在一个函数中,它就不会是一个全局函数

这个问题与全局无关。这是因为闭包是如何工作的。闭包对它们关闭的变量有持久的引用,而不是创建闭包时它们的值的副本。因此,为
onTap
处理程序创建的所有函数都使用相同的单个
date
对象

为了防止这种情况发生,给他们每个人一些自己的东西,让他们在不改变的情况下关闭。如果
dates
是一个数组,请使用
forEach

(对于那些熟悉CoffeeScript但没有发生的人,请注意:
->
前面的
不是通常的
运算符。发生扩展了CoffeeScript,因此使用
!->
而不是
->
声明函数,而不会生成CoffeeScript通常具有的隐式返回值。)。[感谢您指出这一点。]

因此:

…这就变成了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
上关闭,该参数不变

dates.forEach (date) !->
    Dom.section !->
        Dom.div !->
            Dom.text if date.attending then 'Y' else 'N'
            Dom.onTap !->
                Dom.text date.id
dates.forEach(function(date) {
  Dom.section(function() {
    Dom.div(function() {
      Dom.text(date.attending ? 'Y' : 'N');
      Dom.onTap(function() {
        Dom.text(date.id);
      });
    });
  });
});