Reputation:
I have 2 buttons: button1 and Button2. And I have the following code:
$(document).ready(function() {
var message = "hello 1";
$("#button1").on("click", function() {
alert(message);
});
message = "hello 2";
$("#button2").on("click", function() {
alert(message);
});
});
When I click on button1 I am getting "hello 2". I thought this would be closure and I will be getting "hello 1". Please help
Upvotes: 0
Views: 60
Reputation: 44589
Scope in JavaScript is hold in a function. Each time you declare a function, it creates a scope (a closure). So yes, you created a closure, but the behavior you see is the one you should expect.
Here, message
is scoped to the document ready callback. And each click handlers refers to this same scope when searching for the message variable value. As so, the message
variable hold the same value at the time click events are triggered.
To see it, just check the scope as a chain:
"document ready"
- var message (it is declared here and can only have one value at a given time)
- "#button1 click handler"
- no var (so it'll search the parent scope for the value)
- "#button2 click handler"
- no var
Each scope then refers to their parent scope to search for a variable not belonging to its own scope.
Upvotes: 3
Reputation: 123
While those are closures, both of the closures are referencing the message
variable. When the #button1
on click function is called (when the user clicks on it), it uses the current value of the message
variable, which is changed to "hello 2"
before the end of your ready function.
You can avoid this by not re-using the same variable for different messages, as in the below example:
$(document).ready(function() {
var message1 = "hello 1";
$("#button1").on("click", function() {
alert(message1);
});
var message2 = "hello 2";
$("#button2").on("click", function() {
alert(message2);
});
});
Upvotes: 0
Reputation: 780852
A closure doesn't save the value of a variable, it just saves a particular local variable instance. So the assignment message = "hello 2"
updates the variable that is in both closures.
Upvotes: 3
Reputation: 360602
You're defining a global variable message
, and assigning values to it. When the .on('click'...
stuff is executed, the NAME of the message
variable is embedded in those freshly-created functions, not its value at-the-the-time-the-function-is-defined.
So when you do actually click on those buttons, JS takes the variable NAME that was embedded in the functions, looks up its CURRENT value (which is 'hello 2'), and there's your output.
If you were impossibly quick and your browser running relatively slowly, you could POSSIBLY manage to click on your #button1
and get hello 1
, IF the JS engine hasn't actually managed to actually start executing that message = 'hello 2';
line yet. But that's essentially impossible to do. You're not that quick.
Upvotes: 1