在循环中声明的函数引用外部范围的变量可能会导致语义混乱。怎么了?

时间:2017-09-03 19:46:54

标签: javascript

有人能告诉我我的代码有什么问题,尤其是"全屏事件"部分。谢谢!

JSLint说"在循环中声明的引用外部范围变量的函数可能会导致语义混乱。"

function initialize() {
    var mapProp = {
        center: new google.maps.LatLng(45.502808, -73.571486),
    };
    var map = [];
    map[0] = new google.maps.Map(document.getElementById("map1"), mapProp);
    map[1] = new google.maps.Map(document.getElementById("map2"), mapProp);
    map[2] = new google.maps.Map(document.getElementById("map3"), mapProp);

    new google.maps.Marker({
        position: new google.maps.LatLng(45.502808, -73.571486),
        map: map[0], title: 'Sunnyvale '
    });
    new google.maps.Marker({
        position: new google.maps.LatLng(45.502808, -73.571486),
        map: map[1], title: 'Sunnyvale '
    });
    new google.maps.Marker({
        position: new google.maps.LatLng(45.502808, -73.571486),
        map: map[2], title: 'Sunnyvale '
    });


    google.maps.event.addDomListener(window, "resize", function () {
        for (i = 0; i < 3; i++) {
            var center = map[i].getCenter();
            /*var bounds = map[i].getBounds();*/
            var zoom = map[i].getZoom();
            google.maps.event.trigger(map[i], "resize");
            /*map[i].fitBounds(bounds);*/
            map[i].setCenter(center);
            google.maps.event.addListenerOnce(map[i], 'bounds_changed', function(event) {
                this.setZoom(zoom);
            });
        }

    });

    /** Full Screen event */

    for (i = 0; i < 3; i++) {
        var centerChanged = [];
        var zoomChanged = [];
        google.maps.event.addListener(map[i], 'center_changed', function() {

            var centerChanged[i] = map[i].getCenter();
            var zoomChanged[i] = map[i].getZoom();
        });
        $(document).on('webkitfullscreenchange mozfullscreenchange fullscreenchange', function() {
            map[i].setCenter(centerChanged[i]);
            google.maps.event.addListenerOnce(map[i], 'bounds_changed', function (event) {
                this.setZoom(zoomChanged[i]);
            });
        });
    }

}
google.maps.event.addDomListener(window, 'load', initialize);

JSLint说&#34;在循环中声明的引用外部范围变量的函数可能会导致语义混乱。&#34;

2 个答案:

答案 0 :(得分:12)

在你的循环中,我从0开始并迭代直到它等于3.这意味着无论何时在循环完成运行后访问i(例如,在侦听器函数中)它将等于3.你可以请参阅以下代码:

for(var i = 0; i < 5; i++) {
    setTimeout(function() {
        console.log(i);
    }, 1000);
}

这将打印所有5,因为在循环完成迭代后调用该函数。

编辑:要解决此问题,您可以使用javascript的hip新声明语句:let和const。它们仅存在于声明的范围内,因此它们的值不会被覆盖。

for(var i = 0; i < 5; i++) {
    const j = i;
    setTimeout(function() {
        console.log(j);
    }, 1000);
}

编辑2:用var i替换let i似乎也有效:

for(let i = 0; i < 5; i++) {
    setTimeout(function() {
        console.log(i);
    }, 1000);
}

编辑3:如果es6不是一个选项,你可以将i的值绑定到函数:

for(var i = 0; i < 5; i++) {
    setTimeout((function(j) {
        console.log(j);
    }).bind(null, i), 1000);
}

答案 1 :(得分:0)

在循环中,您没有使用i声明var变量,从而在全局范围内隐式创建此变量。