Forum Moderators: open

Message Too Old, No Replies

Nameless (anonymous) functions

No particuar problem, just wondering

         

gergoe

7:44 pm on Jan 14, 2008 (gmt 0)

10+ Year Member



I'm wondering on how the mentioned functions behaving, how they are evaluated by the interpreter?

For instance if I do this

var foo = 123; 
var bar = function(){
alert(foo);
}
bar();

...I get 123 back, right?

But what happens if I do this:

var foo = 123; 
var bar = function(){
alert(foo+111);
}
bar();

...do I get 234? I think so.

Okay, I think it was a piece of cake until now, but this is one is puzzling me:

var foo = 123; 
var bar = function(){
alert(foo);
}
foo += 111;
bar();

...what I'll get back, and why?

Actually the question is, when and how the nameless functions are interpreted, when the variables within are evaluated?

If you can answer the question above easily, can you explain this as well (similar problem, but more likely to be happen in real life)?

for (var foo=1; foo<10; foo++) { 
document.getElementById("something_"+foo).onclick = function(){
alert(foo);
}
}

...what happens if I click on the 6th something, will I get 6 or 10?

coopster

8:32 pm on Jan 14, 2008 (gmt 0)

WebmasterWorld Administrator 10+ Year Member



You'll get
123 
234
234

because foo is defined in the global scope [developer.mozilla.org]. It is the variable you are concerned with and the definitions, not the function. This should answer your second question too. The function in your second issue will echo the current value of the "foo" variable. It does not set the value of foo in the alert to be whatever iteration of the loop it is on.

gergoe

1:53 pm on Jan 15, 2008 (gmt 0)

10+ Year Member



I wouldn't say I understand the explanation completely;

In the first instance javascript does not make difference in definition and implementation? But anyway, What you say is, whatever variable is referenced in the implementation of a nameless function, it is always evaluated, so the value returned will always be the current one? So for the last 'question' the answer is 10 for each of the 10 elements?

If that so, how to go around this? Does a

var localVariable = globalVariable;
helps? I guess not, because there's no difference in passing a variable to alert and assigning a variable to an another, they would be executed in the same way, no?

Fotiman

5:45 pm on Jan 15, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month




// foo, abc, and bar have 'Global' scope because
// they are declared outside of function or object
var foo = 500;
var abc = 678;
var bar = function() {
// This abc does not have 'Global' scope.
// It is only defined within this function
// because we've used 'var' to create a new
// variable within this scope
var abc = 123;
alert(foo); // This will alert global foo's value
alert(abc); // This will always alert 123
}
foo += 321; // global foo = 821
bar(); // alert(821), alert(123)
alert(abc); // alert(678)


Actually the question is, when and how the nameless functions are interpreted, when the variables within are evaluated?

At execution within that scope.


for (var foo=1; foo<10; foo++) {
document.getElementById("something_"+foo).onclick = function(){
alert(foo); // This will always alert 10
};
}

In the example above, you're going to be alerting the value of the global variable foo. Whatever value was last stored in foo is what we'll be alerted (in your example, it's going to be 10).

You might be interested in reading up on JavaScript 'closures'. I suspect that's where your line of questioning is headed.

coopster

3:43 am on Jan 16, 2008 (gmt 0)

WebmasterWorld Administrator 10+ Year Member



I think so too. I like the mozilla developer docs [developer.mozilla.org], perhaps you'll find them helpful as well.

gergoe

11:23 am on Jan 16, 2008 (gmt 0)

10+ Year Member



Great, I think I feel the first waves of understanding :-)

Closures is indeed something I have been looking for, as I already experienced this 'strange' behavior sometimes, and I could not explain why it works sometimes and why it does not in other cases. So it is not the anonymous function which has a different understanding or interpretation, but the way they are threated. If I make closure by using a "function factory", I get the 'strange' behavior.

Actually whenever I assign a function to a variable, I make a closure, but it's only efficient when it's done in a function?

So my last question would need to be rewritten, the onclick should not get the value assigned straight anymore, but from the return value of a function?

Thanks for the help anyway!

coopster

8:22 pm on Jan 16, 2008 (gmt 0)

WebmasterWorld Administrator 10+ Year Member



I'm not quite certain if that is a question there or not? Perhaps an example will help ...
<button id="something_1">Press 1</button><br> 
<button id="something_2">Press 2</button><br>
<button id="something_3">Press 3</button><br>
<button id="something_4">Press 4</button><br>
<button id="something_5">Press 5</button><br>
<button id="something_6">Press 6</button><br>
<button id="something_7">Press 7</button><br>
<button id="something_8">Press 8</button><br>
<button id="something_9">Press 9</button><br>
<button id="something_10">Press 10</button><br>
<script type="text/javascript">
function setSomethingsOnclick(foo)
{
return function() {
alert(foo)
}
}
for (var foo = 1; foo <= 10; foo++) {
document.getElementById("something_" + foo).onclick = setSomethingsOnclick(foo)
}
</script>

gergoe

11:12 pm on Jan 16, 2008 (gmt 0)

10+ Year Member



It was a question, but I'd be expecting a yes or no only :-) But great that you sent it anyway, now I'm sure that I understand it completely.

Thanks a lot!

[edit]Bad English ;-)[/edit]

coopster

6:01 am on Jan 17, 2008 (gmt 0)

WebmasterWorld Administrator 10+ Year Member



LOL! You are welcome, and your English is not bad, it is quite good as a matter of fact!

Yes, the example shows closure by using a "function factory" as you mentioned. It creates a new function for each iteration of the loop and makes it the new handler for the onclick event for each button individually.

Actually whenever I assign a function to a variable, I make a closure, but it's only efficient when it's done in a function?

I wouldn't say that this case is efficient, but it is a somewhat unrealistic case too. Real world applications will likely use more of an object and prototype approach as displayed in the Mozilla/Gecko documentation link earlier. The "function assignment" part of it is going to set the variables and the methods (prototypes) can be defined once and "reused", so to speak.

So my last question would need to be rewritten, the onclick should not get the value assigned straight anymore, but from the return value of a function?

Yes :)