2
<html>
    <head>
    </head>
    <body onload=>  
        <button></button>
        <script>
        function give_show(value) {
            return function() {
                console.log(value);
            }
        }

        var button_element =document.getElementsByTagName('button')[0];
        button_element.addEventListener('load',give_show('bong!'),false)
        </script>
    </body>
</html>

The above code works. in console I got:

bong!

However, if I change this part:

function give_show(value) {
    return function() {
        console.log(value);
    }

to

function give_show(value) {
    return function(value) {
        console.log(value);
    }

I got something like

mouse.event

What's causing that to happen?

FYI: I use Safari console to get the result.

4 Answers 4

2

Nested functions have access to everything defined in the scope in which they are created. So:

function give_show(value){
  return function(){ console.log(value); }
}

when you reference value in the nested function the variable defined in give_show is in scope and is used.

However, when you do this:

function give_show(value){
  return function(value){ console.log(value); }
}

you are returning a function that takes an argument value, so that variable name hides the one defined by give_show.


To make what's happening in the second case more obvious, this code does exactly the same thing, without hiding the value variable from the outer scope:

function give_show(value){
  return function(event){ console.log(event); }
}

The console.log method is using the argument passed to your returned function, and is completely ignoring the value passed to give_show. This is why you're getting 'mouse.event' and not 'bong!' in your second case - event handlers are passed the event as their argument.

Sign up to request clarification or add additional context in comments.

2 Comments

@gdoron: 'bong!' is the initial value passed to the give_show() function and assigned to the value parameter. So the function that give_show() returns will always have access to that parameter. :)
You're using the returned function as the event handler for the button. Event handlers are passed the event as an argument, so that's the value you're getting in your function.
1

This happens because at the time that you're calling console.log(value); the value variable is referring to the parameter of the most inner function. This parameter overrides the value of the parameter you passed into give_show because it has the same name. When that function is called as a result of a click event, the browser will pass the actual click event object as the first parameter into that inner function, which is why you see mouse.event when you do console.log.

Comments

1

You can visualize it this way...

function give_show(value) { // <-- 1. You passed 'bong!'

    return function(value) { // <-- 2. Browser passes the Event object <--------+
//                                                                              |
        console.log(value); // <-- 3. Will use the nearest "value" it finds ----+
   };
}

So the returned function is used as the event handler. When an event occurs, the browser pass an Event object to that function. Since you named the parameter value, console.log will use that.


If you didn't give the name value to the handler function, the next value would be the one defined in your give_show function...

function give_show(value) { // <-- 1. You passed 'bong!' <----------------------+
//                                                                              |
    return function(foo) {   // <-- 2. Browser passes the Event object          |
//                                                                              |
        console.log(value); // <-- 3. Will use the nearest "value" it finds ----+
   };
}

Comments

0

I change load for click on listners and add console.log before return internal function:

<html>
    <head>
    </head>
    <body>  
        <button></button>
        <script>
            function give_show(value) {
                console.log(value);

                return function(value) {
                    console.log(value);
                }               
            }

            var button_element =document.getElementsByTagName('button')[0];
            button_element.addEventListener('click',give_show("bong!"),false);
        </script>
    </body>
</html>

confusion is when give_show is passed to addEventListner. In example give_show run before you click in button and Bong! is write on console. The addEventListner only recognizes function:

function(value) {
    console.log(value);
}               

and event(click) pass to value the position of clicked by mouse. This is same to make this:

button_element.addEventListener('click',function(value) {
                                            console.log(value);
                                        },
                                 false);

If you suppress value parameter value used is from passed to give_show function.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.