Access to mutable variable at event closing

I'm trying to use the mousetrap javascript plugin to handle some key strokes in a similar way, so I thought about encoding them like this

var keys = [ 'b', 'i', 'u']; for (var i=0; i < 3; ++i) { var iKey = keys[i]; var iKeyUpper = iKey.toUpperCase(); Mousetrap.bind( [ 'command+' + iKey, 'command+' + iKeyUpper, 'ctrl+' + iKey, 'ctrl+' + iKeyUpper], ( function( e ) { console.log( "you clicked: " + i ); } ) ); } 

But obviously i is mutable. However, I am not sure how to write a closure where I compete with the event parameter in the response. Suggestions on how to deal with this situation?

+6
source share
2 answers

how to write a closure where I compete with the event parameter in the response

Use a closure either around the whole body of the loop (as @dandavis shows), or use it only around the handler:

 … Mousetrap.bind( [ 'command+' + iKey, 'command+' + iKeyUpper, 'ctrl+' + iKey, 'ctrl+' + iKeyUpper], (function(_i) { // of course you can use the name `i` again return function( e ) { console.log( "you clicked: " + _i ); }; })(i) // and pass in the to-be-preserved values ); 
+5
source

you need to wrap the variable i in the local scope so that it does not synchronize with the "i" in the for loop:

  var keys = [ 'b', 'i', 'u']; for (var i=0; i < 3; ++i) { (function(i){ var iKey = keys[i]; var iKeyUpper = iKey.toUpperCase(); Mousetrap.bind( [ 'command+' + iKey, 'command+' + iKeyUpper, 'ctrl+' + iKey, 'ctrl+' + iKeyUpper], ( function( e ) { console.log( "you clicked: " + i ); } ) ); }(i)); } 

another alternative is to use Array functional methods, which, since they use functions, always have their own scope, and they provide you with the actual value of the element and element:

  var keys = [ 'b', 'i', 'u']; keys.map(function(iKey, i){ var iKeyUpper = iKey.toUpperCase(); Mousetrap.bind( [ 'command+' + iKey, 'command+' + iKeyUpper, 'ctrl+' + iKey, 'ctrl+' + iKeyUpper], function( e ) { console.log( "you clicked: " + i ); }); // end bind() }); // end map() 

The 2nd example will work out of the box in IE9 +, but you can make it work anywhere with the simple Array package package, usually included in IE gaskets ...

+4
source

Source: https://habr.com/ru/post/947753/


All Articles