Javascript - 事件处理程序中的变量范围

标签 javascript event-handling scope

有人可以澄清我对事件处理程序中变量范围的理解吗?看一下下面的代码:

var address = new Array();
address[0] = '1 Smith Street';
address[1] = '2 Smith Street';

for(var rownum=0; rownum<=address.length; rownum++)
{
        if(address[rownum])
                geocoder.geocode( {'address': address[rownum]}, geocodeCallBack);
}


function geocodeCallBack(results, status)
{
        var marker = new google.maps.Marker({
            map: map,
            position: results[0].geometry.location,
            title: results[0].formatted_address
        });

        google.maps.event.addListener(marker, 'click', function(){
                var infowindow = new google.maps.InfoWindow({
                content: marker.title
                });
                // how come this event handler knows the marker variable references the marker variable declared about 10 lines above?
                infowindow.open(map, marker);
        });
}

对于大多数人来说,这段代码看起来很简单。它在谷歌地图上绘制了两个标记。当您单击第一个标记时,它会显示地址“1 Smith Street”。当您单击第二个标记时,它会显示地址“2 Smith Street”。

好吧,我的问题是:为什么两个标记都不显示“2 Smith Street”

过去,我循环遍历对象数组并将事件处理程序绑定(bind)到每个对象。在事件处理程序代码本身中,我会尝试重新引用数组中相应的对象,该对象超出了事件处理程序的范围。因此,在页面加载结束时,所有对象的事件处理程序都引用循环中的最后一个元素。为什么我上面的示例地理编码没有遇到同样的问题?

如果我没有很好地阐明问题,请原谅我。这是因为对情况非常困惑。我似乎无法让我的头脑围绕事件处理程序的变量范围......如果有人可以帮助我澄清,那就太好了。

其他信息/困惑 另一件事...变量 var mark 是在 geocodeCallBack() 的范围内实例化的。当用户在运行时触发 google.maps.event.addListener(marker, 'click', function(){}) 时,标记是否会被销毁?在这种情况下,我应该得到某种未定义的错误?

最佳答案

{'address': address[rownum]} 是一个对象文字。因此,它的值是在执行它所属的语句时确定的,并且将来对 addressrownum 的更改不会影响对象的 address 成员。

您可能习惯于在闭包(从父作用域引用变量的函数)中看到这个问题。这是一个完全不同的问题,因为函数体通常要在一段时间后才会执行。这样的函数继续引用相同的变量,而不仅仅是相同的值。

但在这种情况下,您根本没有在 for 循环中创建任何函数。


不,marker 变量仍然有效——这是闭包所做的一部分。如果你有 C 背景,这确实会显得很神秘。外部函数已返回;本地人怎么可能继续存在!?

答案是这些变量被匿名函数“封闭”,并且运行时会保留它们的存在,直到不再引用匿名函数为止。

关于Javascript - 事件处理程序中的变量范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7002642/

相关文章:

jquery - 当其他 div 动画完成时开始动画 div

javascript - 将 Javascript 函数与 Handlebars 中的按钮一起使用

javascript - 在 Javascript 中更新全局变量时遇到问题

Powershell lambda 作用域

javascript - 通过点击图例隐藏线条谷歌图表,图例不是灰色的,当所有线条都隐藏时会出现麻烦

javascript - 使用 jQuery 禁用悬停效果调整大小

javascript - 设置在 HTML select 元素中选择某些内容时返回的值

coldfusion - Coldfusion中的var关键字以及使用次数

javascript - 添加滚动到 Div 功能以及 UI 自动完成功能

javascript - 如何在 Ionic 3 项目中配置 Amazon AssumeRoleWithWebIdentity 的访问 token ?