简体   繁体   English

在事件闭包中访问可变变量

[英]Accessing mutable variable in an event closure

I am trying to use the mousetrap Javascript plugin to handle some key strokes in a similar fashion, so I thought to code them up as follows:我正在尝试使用mousetrap Javascript 插件以类似的方式处理一些击键,所以我想将它们编码如下:

    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.但是,显然, i是可变的。 However, I am not sure how to write a closure where I am competing the event parameter in the response.但是,我不确定如何编写一个我在响应中与事件参数竞争的闭包。 Suggestions on how to handle this situation?关于如何处理这种情况的建议?

how to write a closure where I am competing the event parameter in the response如何在响应中与事件参数竞争的地方编写闭包

Use a closure either around the whole loop body (as @dandavis) demonstrated), or use it only around the handler:在整个循环体周围使用闭包(如@dandavis 所示),或者仅在处理程序周围使用它:

…
    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
    );

you need to wrap the i variable in a local scope so that it won't sync with the "i" in the for loop:您需要将 i 变量包装在本地范围内,以便它不会与 for 循环中的“i”同步:

   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));
    }

the other alternative is to use functional Array methods, which since they use functions, always have their own scope, and they provide the element value and element index to you intrinsically:另一种选择是使用函数式 Array 方法,因为它们使用函数,所以总是有自己的范围,并且它们本质上为您提供元素值和元素索引:

 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 a simple drop-in Array method compat pack, usually included in IE shims...第二个示例将在 IE9+ 中开箱即用,但您可以使用简单的插入式数组方法兼容包使其在任何地方工作,通常包含在 IE 垫片中...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM