Reputation: 22044
<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.
Upvotes: 2
Views: 143
Reputation: 1500
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.
Upvotes: 0
Reputation: 38798
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.
Upvotes: 2
Reputation:
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 ----+
};
}
Upvotes: 1
Reputation: 11779
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
.
Upvotes: 1