2

使用谷歌地图,我有以下代码:

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 [ i]" 来定义函数的那部分。因此,理想情况下,分配给 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);
};
4

3 回答 3

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到 current 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)
    });
}
于 2012-06-26T19:56:37.827 回答
2

你需要另一个关闭。循环运行后,变量“i”的值为 3。 tileNames[3] => 未定义。但是您创建的每个函数都包含对同一个 i 变量的引用。

尝试这样的事情:

    for (var i = 0; i < tileNames.length; i++) {
      (function(i) {
        //loop body goes here.
      })(i);
    };
于 2012-06-26T19:54:25.537 回答
1

你需要传入i你的getTileUrl函数:

getTileUrl: function(i, coord, zoom) {
        return "/maps/tiles/tiles" + tileNames[i] + "/" + zoom + "_" + coord.x + "_" + coord.y + ".png";
    },
于 2012-06-26T19:51:33.757 回答