1

How to alter the JavaScript code below so that it can avoid exposing the variables and functions to the global scope?

var nMax = 10;
var i = 0;
var step = function(){
 //do stuff
 i += 1;
 if(i < nMax){
 step();
 }else{
 alert('finished');
 }
}
step();

Ideally it would be grateful if the reason behind it could be provided.

Any idea would be very much appreciated!

asked Aug 16, 2011 at 1:52

4 Answers 4

4

Just wrap it in an anonymous function, and call that function immediately:

(function(){
 var nMax = 10;
 var i = 0;
 var step = function(){
 //do stuff
 i += 1;
 if(i < nMax){
 step();
 }else{
 alert('finished');
 }
 }
 step();
})();

Another Example: http://jsfiddle.net/n5Srd/

answered Aug 16, 2011 at 1:54

7 Comments

D'oh. Beat me by six seconds. Actually, my way exposes the function name step, which I thought was what the OP wanted. YMMV.
This way I cannot use step function outside of the anonymous function.
Haha yeah I was quick on this one :) He asked for how to not expose the function as well.
@Shankar That's right, That's what the OP wants. For step, nMax and i to not be exposed to the outer scope.
Either way, it's better to use a function declaration (as in my answer) than a function expression (as in the OP, this answer, and Malvolio's answer). Why? stackoverflow.com/questions/1013385
|
2

The standard way would be

var step = function(){
 var nMax = 10;
 var i = 0;
 return function() {
 //do stuff
 i += 1;
 if(i < nMax){
 step();
 }else{
 alert('finished');
 }
 };
}();
step();
answered Aug 16, 2011 at 1:54

1 Comment

This also doesn't hide the function from the outer scope.
1

An alternative to using a closure: functions are objects, so you can attach values to them just like any other object:

function step()
{
 step.i++;
 if (step.i < step.nMax) step();
 else alert('finished');
}
step();

Or, use an object to namespace the function and variables:

var stepper = 
{
 i: 0,
 nMax: 10,
 step: function ()
 {
 this.i++;
 if (this.i < this.nMax) this.step();
 else alert('finished');
 }
};
stepper.step();

And here's a cleaner version of @PaulPRO's answer which uses a function declaration rather than a function expression:

(function ()
{
 var i = 0,
 nMax = 10;
 function step()
 {
 i++;
 if (i < nMax) step();
 else alert('finished');
 }
 step();
})();
answered Aug 16, 2011 at 1:56

7 Comments

True (+1). However, there is only one "step" function-object. Thus, the behavior may or may not be as desired... also can use arguments.callee to avoid specifying step...
You're right (and probably already know what I'm about to say) but arguments.callee should be avoided since there is a better, more efficient, simple alternative.
This doesn't solve the OP's problem of hiding the function from the outer scope. If he already has a function called step, or a variable named stepper it will conflict
@Paul I took a second look at your code and saw that it will actually work - I mistook it for a slightly different scenario, apologies.
@Matt Ah, I see. No worries :)
|
0

Put in an object so fn gets called via that:-

 var stepHolder = {};
 stepHolder.step = (function(nMax){
 var i = 0;
 return function step(){
 //do stuff
 i += 1;
 if(i < nMax){
 step();
 }else{
 alert('finished');
 }
 };}
 )(10);
 stepHolder.step();
Matt Ball
361k102 gold badges654 silver badges724 bronze badges
answered Aug 16, 2011 at 2:36

2 Comments

That 3 is nMax and should be 10
Stack Exchange sites have this fantastic feature called edit. Check it out.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.