Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/467.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 “Dojo”;关于;循环范围问题的复选框内部更改_Javascript_Events_Dojo_Associative Array - Fatal编程技术网

Javascript “Dojo”;关于;循环范围问题的复选框内部更改

Javascript “Dojo”;关于;循环范围问题的复选框内部更改,javascript,events,dojo,associative-array,Javascript,Events,Dojo,Associative Array,我正在使用Esri的Javascript库3.10,它基于Dojo。我对范围有一个问题,尽管尝试了不同的变体,我仍然得到了相同的结果。也许有更好的方法可以做到这一点,但我似乎不明白 我想通过一个包含键的对象迭代一组复选框,然后使用dojo/on分配一个事件处理程序来基于键设置一个值,但是,on(…)函数中的键“setting”对于所有四次迭代都是相同的 for (var setting in this.appSettings) { console.log(setting); //prin

我正在使用Esri的Javascript库3.10,它基于Dojo。我对范围有一个问题,尽管尝试了不同的变体,我仍然得到了相同的结果。也许有更好的方法可以做到这一点,但我似乎不明白

我想通过一个包含键的对象迭代一组复选框,然后使用dojo/on分配一个事件处理程序来基于键设置一个值,但是,on(…)函数中的键“setting”对于所有四次迭代都是相同的

for (var setting in this.appSettings) {
    console.log(setting); //prints four different things
    if (this.hasOwnProperty(setting)) {
        this.checkboxHandles[setting] =
                On(this[setting], 'change', function (checked) {
                    //this.setValue(setting, checked)
                    console.log(setting) //prints the last 'setting' whenever checkbox is changed
                });
    }
}

因此,On函数内的设置始终是相同的值,即使for循环通过四个唯一的键循环。首先,为什么会发生这种情况,有什么建议可以解决这个问题?

这是JavaScriptessentials的一个要点。闭包总是通过引用引用其外部范围变量。这意味着事件处理程序引用
设置
变量。但是,当for循环继续时,
设置
变量将引用数组中的下一个值

这个问题的解决方案是我们称之为IIFE或立即调用的函数表达式

如果将事件处理程序替换为返回函数的函数,例如:

On(appSettings[setting], 'change', function (setting) {
  return function(checked) {
    //this.setValue(setting, checked)
    console.log(setting) //prints the last 'setting' whenever checkbox is changed       
  }
}(setting));
因此,这里发生的是
设置
变量被传递给函数包装器,其优点是它们是通过值传递的,而不是通过引用传递的

因此,如果从该函数内部访问
设置
变量,它将引用传递给该函数的局部范围
设置
变量

它看起来有多奇怪,它的工作原理是:
可以找到一个有趣的幻灯片来解释这种行为。

感谢您的精彩回答!我以前肯定听说过闭包,也见过闭包,但从来没有实际应用过闭包(或者我是这么认为的)。没问题,把IIFE放在脚本文件周围是一种常见的做法。例如,许多jQuery插件这样做是因为它们通过值传递jQuery对象,因此以后不能对其进行更改。