Javascript闭包和处理程序

时间:2013-05-28 18:05:12

标签: javascript jquery closures

我有这个javascript函数:

 function files() {
    var dropResult = false;

    $('#button1').on('click', function() {
           dropResult = true;
    });

    $('#button2').on('click', function() {
          dropResult = false;
    });

   return dropResult;           
}
files();

单击其中一个按钮后, dropResult 变量必须更改。如何正确编写它以使我的函数返回 dropResult 变量的正确值? 我知道,这是关于闭包但我真的不明白如何解决这个问题。 谢谢你的帮助。

5 个答案:

答案 0 :(得分:3)

我相信你想要

var files = (function () {
    var dropResult = false;

    $('#button1').on('click', function () {
        dropResult = true;
    });

    $('#button2').on('click', function () {
        dropResult = false;
    });

    return function () {
        return dropResult;
    };
})();

http://jsfiddle.net/gaby/9b7yK/

演示

答案 1 :(得分:0)

    var dropResult = false;

    $('#button1').on('click', function() {
           dropResult = true;
    });

    $('#button2').on('click', function() {
          dropResult = false;
    });

    function files() {
       return dropResult;           
    }

假设你需要的是获得dropResult的正确值,上面的代码应该有用。

答案 2 :(得分:0)

我将“扩展”Gaby aka的答案,但我认为他是完全正确的。我将在私人和公共方法中更具体。以及如何访问它们,实际上还将事件绑定到一个特定的按钮,你可以在这里查看小提琴[http://jsfiddle.net/qsDz6/] [1]

HTML

<input type="button" id="button1" value="button 1" />
<input type="button" id="button2" value="button 2">

<input type="button" id="actualValue" value="Actual Value of _dropResult">

JS

var files = (function(__name){
     var _name = __name;
     var _dropResult = null;

    /*Private  */
    function init(){
        eventHandler();
    }    

     function eventHandler(){
       $(document).on("click","#button1", $.proxy($r.actionButton1,this));
       $(document).on("click","#button2", $.proxy($r.actionButton2,this));
       $(document).on("click", "#actualValue", $.proxy($r.dropResult,this));
     }

    /*Public */
     var $r = {}; //will make public any method

     $r.actionButton1 = function(){         
       _dropResult = true;        
       alert(_dropResult);
     }

     $r.actionButton2 = function(){
       _dropResult = false;         
        alert(_dropResult);
     }        

     $r.dropResult = function(){alert(_dropResult);}


     init();    

     return $r;    
})("files");

快乐编码

答案 3 :(得分:-1)

更新:尽管最多投票的解决方案同时发布,同样优雅,并且在逻辑上等同,但这个答案在某种程度上已被低估了。另一个解决方案只是选择在函数闭包中捕获局部变量而不是对象闭包。

作为选民的责任是实际阅读和思考这些解决方案的作用,而不仅仅是投票给熟悉的人或者声誉最高的人提供的答案。

我回答的责任是只回答不是人气竞赛的问题,但是当(A)我肯定知道一个有效答案并愿意花时间解释和维持这个答案时;或者(B)对于一些讨论问题,其中没有什么比“答案”那么明确,那么只有在我根据自己的经验多次遇到问题并根据我的实际经验对其进行说明时才会这样。

出于这个原因,我正在离开我的答案(正如我过去所做的那样),即使社区中的某个人匿名决定对其进行投票而没有任何解释原因。

请记住,Stack Overflow的答案旨在成为有用问题的有用解决方案的存储库,以便将来所有程序员的利益。值得展示两种不同的方法,而不是单一方法。

是的,另一个解决方案很优雅,并使用匿名函数闭包很好地捕获局部变量。然而,在我看来,我的解决方案在Stack Overflow的目的背景下略胜一筹,因为这个解决方案可以很容易地修改为可重用的函数来创建许多监控变量。另一个解决方案需要进行一些反卷积,以使其对一个监视函数的多个静态实例化非常有用。

function files() {
    var dropResult = {};

    $('#button1').on('click', function() {
           dropResult.result = true;
    });

    $('#button2').on('click', function() {
          dropResult.result = false;
    });

   return dropResult;           
}
var dropObject = files();

变量dropObject是一个“监控变量”,可以在任何地方使用,以便检查您监控的状态(在这种情况下,用户最近一次点击的用户最后一次指定的替代方案) button1或button2。)

在使用files()结果的代码中,您可以执行此操作

if (dropObject.result) {
    /* do something here that you want to do when the result is true */

} else {
    /* do something here when the result is false */
}

我建议存储比truefalse更有意义的内容(例如,如果你想添加第三个按钮然后监视最后一次点击哪三个,那该怎么办?)。 / p>

注意:以下是我将如何编写更小,更高效的可重用监视功能供我使用(不是硬连接函数内的任何参数或名称)并将其应用于此场景: < / p>

function clickMonitor(ids) {
var i, f = function() { i = this; }; ids = ids.match(/(\S+)/g) || [];
for (i=0; i<ids.length; i++)
document.getElementById(ids[i]).onclick = f;
return function() { return i; };
}

下一部分只是创建一个dropResult变量 除了您之外,“即插即用”代替您的dropResult变量 必须检查dropResult()是真还是假 (函数调用)而不仅仅是dropResult

dropResult = (function() {
var x = clickMonitor('button1 button2');
return function() { return x().id == 'button1'; };
})();

一般来说,这就是你如何使用它(当然,如果需要,可以传递两个以上的按钮ID):

getMostRecentClickedButton = clickMonitor('button1 button2');

调用getMostRecentClickedButton()会返回整个按钮 最近点击的对象,以便您可以使用它来执行某些操作,例如 使字体粗体等,而不需要执行另一个中间 jQuery或JavaScript程序。

答案 4 :(得分:-2)

我不明白需要这个,但一种方法是

function files() {
   files dropResult = false;
   return files.dropResult;           
}
$(document).on('click', '#button1', function() {
  files.dropResult = true;
});

$(document).on('click', '#button2', function() {
  files.dropResult = false;
});
files();