views:

188

answers:

1

I have a lengthy JavaScript file that passes JSLint except for "used before it was defined" errors.

I used normal function declarations, as in...

function whatever() {do something;}

as opposed to...

var whatever = function(){do something;};

and consistent with Steve Harrison's reply to an earlier post...

Assuming you declare all your functions with the function keyword, I think it becomes a programming-style question. Personally, I prefer to structure my functions in a way that seems logical and makes the code as readable as possible. For example, like you, I'd put an init function at the top, because it's where everything starts from.

... I like seeing the functions in an order that makes sense to me.

The script functions perfectly in the several browsers tested (e.g., FireFox, Safari, Mobile Safari, Fennec, IE, Chrome, Midori, etc.).

Here's the problem: I want to use the script inside of an iPhone app being built with Titanium but its compiler stops with "used before defined" errors.

How can I get around this?

This might be a stupid question but also... If functions need to be called in a particular order, how does one resolve the matter of a called function needing to call back to the function that originally called it? For instance...

function buildMenu(){
     Display a list of five menu items, each of which calls a function to build the associated screen.
}

function screen1() {
     Display the screen associated with menu item #1.
}

If the functions need to be declared in order, function screen1 would need to precede function buildMenu. But what if, under certain conditions, screen1 cannot be built and hence wants to redisplay the menu (i.e., calling a function that is technically not yet declared)?

Oh yeah... one more question: Are there websites or programs that automatically re-sequence the functions rather than requiring the programmer to do it manually?

+2  A: 

No, EM's answer is NOT the right solution. Try running this JavaScript:

(function () {
   foo(); // right

   var foo = function () {
     console.log("wrong");
   };

   foo(); // wrong

   function foo() {
     console.log("right");
   }

   foo(); // wrong
}());

This is because the interpreter will first read the function declaration, create the name foo as a function that prints "right", then reads the var statement, and find that there is already a name foo so it will skip creating a new variable with the value undefined, as normally happens. Then it processes the code, line-by-line, which includes an assignment to foo. The function declaration does not get reprocessed. Maybe this will behave differently in Titanium, but try this in Firebug and you'll get what I got.

A better solution is:

var screen1, buildMenu;

screen1 = function () { buildMenu(); };
buildMenu = function () { screen1(); };

This will also pass JSLint, and produce the correct behavior.

bcherry
Thank you. I didn't have the time to check the previous solution, so I'll give this a shot. Thanks again.
Alan Neal
Good point. I didn't actually test my solution. I just ran it through jslint.
EndangeredMassa
Worked perfectly both in JSLint and Titanium. Thanks again. B.BTW: For anyone who needs to make this change to an existing script, as I did, an easy shortcut for creating the global variable list of functions is to run the script through JSLint and copy the Global list from the bottom of the results. It's not 100% accurate but in my situation, with about 100 functions, I only needed to make a half-dozen adjustments.
Alan Neal