如何在分配给数组索引的对象上调用方法
How can I call a method on an object assigned to an array index?
为了在谷歌地图内为标记创建信息窗口,我使用了一个数组在我的for循环中创建"一次性对象"。但是,我的方法似乎不起作用。单击标记没有任何作用,当我检查控制台时,我收到以下错误消息:
Uncaught TypeError: Cannot call method 'open' of undefined
当我不将对象分配给数组索引时,单击任何创建的标记只会打开最后一个信息窗口(这意味着当对象被覆盖时,它会更新对先前对象的所有引用)。
我怎样才能规避这种情况?
markers = []
infowindows = []
counter = 0
for location in exports.response.locations
myLatlng = new google.maps.LatLng(location.latitude, location.longitude);
markers[counter] = new google.maps.Marker(
position: myLatlng
map: map
title: location.name
)
contentString = '<div id="info_content_' + location.id + '">' + '<h3>' + location.name + '</h3>' + '<ul>' + '<li>' + location.address + ', ' + location.city + '</li>' + '</ul>'
infowindows[counter] = new google.maps.InfoWindow(content: contentString)
google.maps.event.addListener markers[counter], "click", ->
infowindows[counter].open(map, markers[counter])
counter++
注意
问题区域是上面代码中的倒数第三行。( infowindows[counter].open(map, markers[counter])
)
答
几乎对这个问题的每个回复都帮助我找到了解决方法,但是 - 为了记录(以及以后准备的任何人),我用 foreach 解决了它:
markers = []
infowindows = []
exports.response.locations.forEach (location) ->
myLatlng = new google.maps.LatLng(location.latitude, location.longitude);
markers[location.id] = new google.maps.Marker(
position: myLatlng
map: map
title: location.name
)
contentString = '<div id="info_content_' + location.id + '">' + '<h3>' + location.name + '</h3>' + '<ul>' + '<li>' + location.address + ', ' + location.city + '</li>' + '</ul>'
infowindows[location.id] = new google.maps.InfoWindow(content: contentString)
google.maps.event.addListener markers[location.id], "click", ->
infowindows[location.id].open(map, markers[location.id])
我认为您的问题是counter
将不再具有有效的索引:
for location in exports.response.locations
google.maps.event.addListener markers[counter], "click", ->
infowindows[counter].open(map, markers[counter])
counter++
counter
在 onClick 处理程序闭包中捕获。
在 onClick 处理程序运行之前,它将超出边界递增。
所有这些处理程序最终都将对 counter
使用相同的值。
addListener 异步触发代码。因此,调用侦听器的回调函数时计数器的值与声明函数时的值不同。若要将变量冻结为声明函数时的值,必须将它们放在闭包中。下面的完整证明选项。在循环中声明 currentCounter 应该就足够了,但它可能有助于显式使用闭包。
markers = []
infowindows = []
counter = 0
for location in exports.response.locations
myLatlng = new google.maps.LatLng(location.latitude, location.longitude);
markers[counter] = new google.maps.Marker(
position: myLatlng
map: map
title: location.name
)
contentString = '<div id="info_content_' + location.id + '">' + '<h3>' + location.name + '</h3>' + '<ul>' + '<li>' + location.address + ', ' + location.city + '</li>' + '</ul>'
infowindows[counter] = new google.maps.InfoWindow(content: contentString)
google.maps.event.addListener markers[counter], "click", (function(infowindows, markers, currentcounter) {
return function() { infowindows[currentCounter].open(map, markers[currentCounter]) }
})(infowindows, markers, counter)
counter++
参见 JavaScript 闭包内部循环 – 简单的实际示例以获取更多实际示例
相关文章:
- 从联合js rect对象调用引导模式
- 为什么可以't我用Set对象调用Array.prototype.map
- 从数组(JS)中的对象调用函数
- 在CouchDB Map函数中发出日期时-对日期对象调用的内容
- 'stepUp'对未实现接口HTMLInputElement的对象调用
- 从设置为原型的对象调用属性
- 类型错误:'单击'对未实现接口HTMLElement的对象调用
- 从javascript对象调用函数
- 得到"未捕获的类型错误:未定义的不是函数“;当试图从对象调用get()或set()时
- 子对象调用兄弟姐妹'方法
- 是否可以在函数构造函数中识别哪个对象调用它,并在错误的对象调用时中止创建
- Angularjs:错误:'追加'对未实现接口FormData的对象调用.jQuery.param/ad
- 为什么这个带有对象调用函数的Javascript setInterval在传入回调时不计算内部参数
- 生成自定义对象调用
- 对非对象调用了gulp jscs Object.keys
- JavaScript 从子对象调用父函数
- 对字符串对象调用 .localeCompare 与构造特制的 Intl.Collator 对象之间的性能差异
- 一次将所有对象调用到函数中,返回每个对象的特定计算
- 不能从jquery对象调用的Javascript方法
- 从具有事件侦听器的对象调用函数