Closing jQuery: how to get value from click function

I don’t quite understand the closure of JS, and I think it can solve my problem. here he is:

I have something like this:

$(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. I need to get the value of "r" as 0 or 1. I know that I have to use closure, but I don't know how to do it. Thanks for your experience!

+4
source share
3 answers

You cannot do this, it is impossible, for reasons not related to closing.

Without calling the code that sets int_val , you only define the code and say, "When the buttons are clicked, call that code." The code will not be executed at the time of launching return int_val , it will be executed at some point in the future when the button is clicked.

This code block 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 pass values ​​back from asynchronous functions, you should use 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 `done` handler dfd.resolve(int_val); }); return dfd.promise() } 

The calling code will receive a promise object that can add callbacks:

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

I cannot understand what you meant int_val to execute the call code.

+3
source

A closure occurs when an internal function refers to something that is defined outside of it. To illustrate:

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

What you want to do is that your int_val variable will be available where both the popup_modal and popup_confirme tags can be accessed.

Many ways to do this are based on your example, but something simple that might 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); }()); 
+1
source

Technically, all JavaScript functions are closures, as they are objects with a chain of scopes attached to them. Closing is simply a combination of a functional object and a region (a set of variable bindings).

The scope is really quite simple. Javascript uses a lexical scope, which means that the function executes in the scope of the variables that acted when they were defined. Simply put, an external function cannot read a value from an internal function unless it returns. The inner function can read all the values ​​declared in the outer function.

When most people talk about closure, they actually refer to the act of returning an element from an internal nested function to an external function in which it was 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 in the inner scope. As you should already understand, this is invisible to an external function, so it 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; }); }); }()); 

Hope this all simplifies you.

+1
source

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


All Articles