使用Google地图,我有以下代码:
var tileNames = ["base", "parking", "access"];
var mapType = {};
for (var i = 0; i < tileNames.length; i++) {
var tileOptions = {
getTileUrl: function(coord, zoom) {
return "/maps/tiles/tiles" + tileNames[i] + "/" + zoom + "_" + coord.x + "_" + coord.y + ".png";
},
tileSize: new google.maps.Size(256, 256)
};
mapType[tileNames[i]] = new google.maps.ImageMapType(tileOptions);
};
这是我的问题:执行该函数时,“getTileUrl”函数中的“tileNames [i]”未定义。但是,“tileNames”数组仅用于定义“mapType”对象,因此,与传递给函数的“coord”和“zoom”变量不同,我希望使用“tileNames [我]“定义函数的那一部分。因此,理想情况下,分配给mapType.parking的函数看起来像这样......
function(coord, zoom) {
return "/maps/tiles/tilesparking/" + zoom + "_" + coord.x + "_" + coord.y + ".png";
};
...在第一段代码中定义函数之后。有没有办法获取变量/数组的值并使用它来静态定义函数,同时将其他两个变量保持为变量。
编辑:查看下面的各种答案,以下是迄今为止我能够取得的最佳成绩。虽然在更一般的情况下绑定可能是理想的方法,但在这种特定情况下,“getTileUrl:”显然需要特定的语法,并且在为其定义的函数周围放置绑定会导致映射错误。在尝试KGZM的建议时,它适用于所有最新的,而不是IE8及以下版本。
var tileNames = ["beloit", "parking", "access_p"];
var mapType = {};
for (var i = 0; i <= (tileNames.length - 1); i++) {
(function(i) {
tileOptions = {
getTileUrl: function(coord, zoom) {
return "/maps/tiles/tiles" + tileNames[i] + "/" + zoom + "_" + coord.x + "_" + coord.y + ".png";
},
tileSize: new google.maps.Size(256, 256)
};
mapType[tileNames[i]] = new google.maps.ImageMapType(tileOptions);
})(i);
};
答案 0 :(得分:4)
有一个可以很好地处理这个问题的函数式编程概念
基本上,您的函数实际上有三个参数,zoom
变量,coord
对象和tileNames[i]
值,但您希望修复tileNames[i]
值在代码中一次使用特定值,并将其他两个变量保留为实际变量。
function getTileUrlBuilder(tilename) {
return function(coord, zoom) {
return "/maps/tiles/tile" + tilename + "/" + zoom + "_" + coord.x + "_" + coord.y;
};
}
然后你可以在你的循环中使用这个功能。但是,由于这实际上是一种常见操作,因此您可以使用bind
方法来处理此问题:
(function(tilename, coord, zoom) {
return "/maps/tiles/tile" + tilename + "/" + zoom + "_" + coord.x + "_" + coord.y
}).bind(this, tileNames[i]);
这会将隐式this
“绑定”到当前this
,然后将第一个参数绑定到当前值tileNames[i]
。
编辑:我认为这应该是工作代码。
var tileNames = ["beloit", "parking", "access_p"];
var mapType = {};
function getTileUrlFull(tileName, coord, zoom) {
return "/maps2/tiles/tiles" + tileName + "/" + zoom + "_" + coord.x + "_" + coord.y + ".png"
}
for(var i = 0; i < tileNames.length; i++) {
mapType[tileNames[i]] = new google.maps.ImageMapType({
getTileUrl: getTileUrlFull.bind(this, tileNames[i]),
tileSize: new google.maps.Size(256, 256)
});
}
答案 1 :(得分:2)
你需要另一个闭包。循环运行后,变量'i'的值为3. tileNames [3] =&gt;未定义。但是你创建的每个函数都包含对同一个i变量的引用。
尝试这样的事情:
for (var i = 0; i < tileNames.length; i++) {
(function(i) {
//loop body goes here.
})(i);
};
答案 2 :(得分:1)
您需要将i
传递到getTileUrl
函数:
getTileUrl: function(i, coord, zoom) {
return "/maps/tiles/tiles" + tileNames[i] + "/" + zoom + "_" + coord.x + "_" + coord.y + ".png";
},