2017-03-08 52 views
1

每次运行此循环时,marker数组中的每个标记都会将其图标从let icon = iconLoader.getIcon(data[index][5]);的结果中覆盖。 让每个标记具有最后加载的图标,而不是在for循环的每次传递期间加载图标。来自内部的值,用于循环覆盖循环外的数据

我认为将图标传递给闭包基本上会通过值传递它,防止它被覆盖在闭包范围之外,但这似乎不适用于我。我错过了什么?

var markers = [] 
for (var index in data) {  
    let icon = iconLoader.getIcon(data[index][5]); 
    var createMarker = (function (i) { 
     return function() { 
      var marker = new L.marker([data[index][2], data[index][3]]) 
       .setIcon(i)  
      markers.push(marker); 
     } 
    })(icon); 
    createMarker(); 
} 

var iconLoader = (function() { 
    var icon = L.icon({ 
     // options 
    });  
    return { 
     getIcon: function (iconName) { 
      // do stuff to get icon 
      return icon; 
     } 
    }; 
}()); 

JSFiddle

+0

对象和数组除非你创建一个副本 – mhodges

+0

你也永远不会调用由您IIFE..at返回的功能至少不总是按引用传递无论如何,你提供的代码。 – mhodges

+0

你可以发布'setIcon'函数的内容吗?最好是标记类的结构呢? – mhodges

回答

1

所以,正如我在原来的评论中提到,JavaScript对象和数组引用始终被传递,除非你明确地创建并传递一个副本。代码中没有任何内容是错误的,并且不会导致此问题 - 实际上,传单在内部如何处理对象引用时存在问题。避免这种情况的方法是对iconLoader.getIcon()的结果执行深层副本。如果你使用的是jQuery,你可以通过使用$.extend()来简单地做到这一点。

for (var index in data) { 
    let icon = $.extend(true, {}, iconLoader.getIcon(data[index][2])); 
    var marker = new L.marker([data[index][0], data[index][1]]) 
    .setIcon(icon);  
    markers.push(marker); 
} 

如果不是,您可以看看非jQuery解决方案 - 它不是理想的,但它们无处不在。

+1

完全适合我。谢谢! –

0

当mhodges正在写他的答案时,我正在打字。我会继续发布,因为这是一个不同的解决方案,也为我解决了这个问题。

在看完mhodges的演示后,我注意到他已经设置了图标加载器,与我的图标有点不同。他有iconloader为对象...

var iconLoader = { 
    getIcon: function (elem) { 
     return elem; 
    } 
} 

而我被设置为关闭...

var iconLoader = (function() { 
    var icon = L.icon({ 
     // options 
    });  
    return { 
     getIcon: function (iconName) { 
      // do stuff to get icon 
      return icon; 
     } 
    }; 
}()); 

我想,也许我可以尝试设置它有点不同,看看如果这有所作为,VOILA!

const proto = { 
     getIcon (iconName) { 
      var icon = L.icon({ 
       // options 
      }); 
      // do stuff to get icon 
      return icon; 
     } 
    }; 

function factoryIcon() { 
    return Object.create(proto); 
} 

,然后抓起图标,

const iconFactory = factoryIcon(); 
let icon = iconFactory.getIcon(data[index][5]);