简体   繁体   English

jQuery闭包:如何从函数单击中获取值

[英]jQuery closure: How to get a value from a function click

I don't quite understand JS closures and I think it can solve my problem. 我不太了解JS闭包,我认为它可以解决我的问题。 here it is: 这里是:

I have something like that : 我有类似的东西:

$(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;
}

I would like to get my int_val returned by the button click event. 我想通过按钮单击事件返回我的int_val。 I need to get the 'r' value as 0 or 1. I know I should use closures, but I dont know how to do it. 我需要将'r'值设为0或1.我知道我应该使用闭包,但我不知道该怎么做。 Thank you for your expertise ! 感谢您的专业知识!

You can't do this, it's impossible, for reasons unrelated to closures. 由于与封闭无关的原因,你无法做到这一点,这是不可能的。

Your not calling the code that sets int_val , you're only defining the code, and saying "when .buttons are clicked, invoke this code". 你没有调用设置int_val的代码,你只是定义了代码,并且说“当点击.buttons时,调用这个代码”。 The code will not have been executed at the point you run return int_val , it will be executed at some point in the future when the button is clicked. 代码将不会在您运行return int_val执行,它将在将来单击按钮时执行。

This block of code cannot logically work: 这段代码无法在逻辑上工作:

// 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;

If you want to communicate values back out of asynchronous functions, you should use promises: 如果要从异步函数中传递值,则应使用promises:

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

The calling code will receive a promise object, which it can add callbacks to: 调用代码将接收一个promise对象,它可以将回调添加到:

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

I can't intuit beyond this point what you meant int_val to do up in your calling code. 除了这一点,我不能int_val意你在你的调用代码中使用int_val

A closure occurs when an inner function references something defined outside it. 当内部函数引用在其外部定义的内容时,会发生闭包。 To illustrate: 为了显示:

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

What you seem to want done is that your int_val variable be accessible where both popup_modal and popup_confirme can get to it. 你似乎想要做的是你的int_val变量是可访问的, popup_modalpopup_confirme都可以访问它。

Many ways to do it based off your example, but something as simple as this can work: 根据你的例子,有很多方法可以做到这一点,但这样简单的事情可以起作用:

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

}());

Technically all JavaScript functions are closures as they are objects with a scope chain attached to them. 从技术上讲,所有JavaScript函数都是闭包,因为它们是附加了作用域链的对象。 A closure is simply the combination of a function object and a scope (a set of variable bindings). 闭包只是函数对象和作用域(一组变量绑定)的组合。

Scope is actually pretty simple really. 范围实际上非常简单。 Javascript uses lexical scoping which means that function are executed in the variable scope that was in effect when they were defined. Javascript使用词法作用域,这意味着函数在定义它们时生效的变量作用域中执行。 Simply put, An outer function cannot read a value from an inner function unless is is specifically returned. 简单地说,外部函数不能从内部函数读取值,除非特别返回。 An inner function can read all values declared in an outer function. 内部函数可以读取外部函数中声明的所有值。

When most people talking about closures they are actually referring to the act of returning an item from an inner nested function to the outer function in which it has been defined. 当大多数人谈论闭包时,他们实际上指的是将项目从内部嵌套函数返回到已定义它的外部函数的行为。

eg 例如

// 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();

}

In your example you are trying to get a value that was declared and not returned on the inner scope. 在您的示例中,您尝试获取已声明但未在内部范围上返回的值。 As you should understand by now, this is invisible to the outer function so cannot work. 正如您现在应该理解的那样,这对外部函数是不可见的,因此无法工作。

This can be rewritten as such: 这可以这样重写:

// 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;

        });    
    });

}());

Hopefully this makes it all a little bit more clear to you. 希望这对你来说更加清晰。

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

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