4

我不太了解 JS 闭包,我认为它可以解决我的问题。这里是:

我有类似的东西:

$(document).ready(function () {
    $("#buttonConfirm").click(function () {
        popup_confirme();
    });
});
function popup_confirme() {
    var r = popup_modal();
}
function popup_modal() {
    var int_val = 0;
    $(".button").click(function () {
        int_val = ($(this).val() == 'yes' ? '1' : '0');
    });
    return int_val;
}

我想让我的 int_val 由按钮单击事件返回。我需要将 'r' 值设为 0 或 1。我知道我应该使用闭包,但我不知道该怎么做。感谢您的专业知识!

4

3 回答 3

3

由于与关闭无关的原因,您不能这样做,这是不可能的。

您没有调用设置的代码int_val,您只是定义代码,并说“当单击 .buttons 时,调用此代码”。代码不会在您运行时执行return int_val,它将在将来单击按钮时执行。

此代码块在逻辑上无法正常工作:

// First line run
var int_val = 0;

// Second line run
$(".button").click(function () {
    // This line runs in the future, or maybe never, if the button isn't clicked
    int_val = ($(this).val() == 'yes' ? '1' : '0');
});

// Third line run
return int_val;

如果你想从异步函数中传回值,你应该使用 Promise:

function popup_modal() {
    var dfd = $.Deferred();

    $(".button").click(function () {
        int_val = ($(this).val() == 'yes' ? '1' : '0');

        // Allow int_val to find its way back to the calling code's `done` handler
        dfd.resolve(int_val);
    });

    return dfd.promise()
}

调用代码将收到一个 Promise 对象,它可以将回调添加到:

function popup_confirme() {
    var r;
    popup_modal().done(function (int_val) {
      r = int_val;
    }
}

超出这一点,我无法直观地理解您int_val在调用代码中的意图。

于 2013-06-14T14:13:43.567 回答
1

当内部函数引用外部定义的内容时,就会发生闭包。为了显示:

function outer() {
    var foo = 1;
    element.click(function () {
        // this function creates a closure on foo.
        alert(foo);
    });
};

您似乎想要做的是您的int_val变量可以在两者都可以访问popup_modal的地方访问popup_confirme

根据您的示例有很多方法可以做到这一点,但是像这样简单的方法可以工作:

(function () {

    var int_val = 0;

    var popup_modal = function () {
        int_val = $(this).val() === 'yes' ? 1 : 0;
    };

    var popup_confirme = function () {
        // your original code here doesn't really do anything
        alert(int_val);
    };

    $('.button').click(popup_modal);
    $('#buttonConfirm').click(popup_confirme);

}());
于 2013-06-14T14:14:53.353 回答
1

从技术上讲,所有 JavaScript 函数都是闭包,因为它们是带有作用域链的对象。闭包只是函数对象和范围(一组变量绑定)的组合。

范围实际上非常简单。Javascript 使用词法范围,这意味着函数在定义它们时有效的变量范围内执行。简单地说,外部函数不能从内部函数中读取值,除非特别返回。内部函数可以读取外部函数中声明的所有值。

当大多数人谈论闭包时,他们实际上是指将项目从内部嵌套函数返回到定义它的外部函数的行为。

例如

// I am the outer function.
function outer (){

var outerVariable = "I am available to inner functions.";

    // I am an inner function. I was declared in the scope of the outer 
    // function and as such all the variables declared in that scope are 
    // available to me.
    function inner (){

        // This will return => "I am available to inner functions." as we can 
        // read the outer declaration.
        var innerReadValue = outerVariable; 

        // This will be available only to the inner function as it is 
        // not returned.
        var privateVariable = "I am private";

        // This will be available to the outer function as we are returning it 
        // on the next line.
        var publicVariable = "I am available to outer functions";

        // Make publicVariable public. This is what most people refer to 
        // when talking about closures. 
        return publicVariable; 

    }

    // Read the inner functions publicVariable declaration.
    // Returns => "I am available to outer functions"
    var outerReadValue = inner();

}

在您的示例中,您试图获取一个已声明且未在内部范围内返回的值。正如您现在应该理解的那样,这对外部函数是不可见的,因此无法工作。

这可以重写为:

// This is called an Immediately Invoked Function Expression. IIFE, It 
// basically wraps your code in a function hiding all internal declarations
// from the global scope and then invokes it. You don't want to pollute the 
// global scope.
(function(){

    // Declare this outside so all functions can read it.
    var int_val = 0;

    // Declare this outside so all functions can read it.
    var popup_confirm = function(){
        // "int_val" is available here.
        return int_val;
    };

    // Although your function runs automatically, we delay binding until
    // the DOM is ready.
    $(document).ready(function(){

        $("#buttonConfirm").click(function(){
           // Provide feedback. "popup_confirm" is available here
           // since is declared in the outer scope.
           return popup_confirm();
         });

        $(".button").click(function(){
            // Set the value of int_val that has been declared in the outer 
            // scope.
            int_val = $(this).val() === "yes" ? 1 : 0;

        });    
    });

}());

希望这能让你更清楚一点。

于 2013-06-14T14:56:28.490 回答