Functions declared within loops referencing an outer scoped variable may lead to confusing semantics. What is wrong? [duplicate]

匿名 (未验证) 提交于 2019-12-03 00:46:02

问题:

This question already has an answer here:

  • 37 answers

Can someone tell me what is wrong with my code, especially the "Full screen event" part. Thanks!

JSLint says "Functions declared within loops referencing an outer scoped variable may lead to confusing semantics."

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 says "Functions declared within loops referencing an outer scoped variable may lead to confusing semantics."

回答1:

In your loop, i starts at 0 and iterates until it's equal to 3. That means that whenever you access i after the loop has finished running (for example, in a listener function) it will be equal to 3. You can see this in the following code:

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

That will print all 5s because the function is being called after the loop has finished iterating.

Edit: To fix the issue, you can use javascript's hip new declaration statements: let and const. They exist only in the scope that they are declared, and their values are therefore not overwritten.

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

Edit 2: Replacing var i with let i appears to work as well:

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

Edit 3: If es6 isn't an option, you could bind i's value to the function:

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


回答2:

In your loop, you are not declaring the i variable with var, thereby implicitly creating this variable in the global scope.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!