5

Searching for the JSLint error "was used before it was defined" i've found these:

Problem

None of those answers WHY the error is shown.

Elaboration

According to the ECMA-262 Specification functions are evaluated before execution starts, hence all functions declared using the function keyword are available to all the code idenpendent of the place they were declared (assuming they are acessible on that scope).

This is otherwise known as hoisting.

Douglas Crockford seems to think it is better to declare every function before the code that uses it regardless of the hoisting effect.

According to StackOverflowNewbie in his question, this raises some code organization problems. Not to mention some people, like me, prefer to declare their functions underneath the main/init code.

On those questions there are some ways to avoid or fix the error, such as using function expressions vs function declarations. But none of them showed me the reason of the error. Not even Crockford's site.

Question(s)

Why is it an error to call a function before the declaration, even if it was declared using the function keyword?

Is it better to use function expressions instead of function declaration in the JSLint context? If one is preferred, why?

Note

Not looking for answers like:

  • Crockford is a tyrant
  • Is just Crockford's opinion

Thank you :*

Community
  • 1
  • 1
7hi4g0
  • 3,729
  • 4
  • 22
  • 32
  • 4
    But is **is** Crockford's opinion! – Quentin Dec 26 '13 at 14:45
  • Does jshint complain about this? – Dagg Nabbit Dec 26 '13 at 14:48
  • 2
    JSLint is a tool to check if your code adheres to the coding style Crockford likes. It's not meant for validating against the specification or for ensuring compatibility with JS engines. "It's just Crockford's opinion" is a valid (and only) answer to most JSLint questions. – JJJ Dec 26 '13 at 14:49
  • 1
    Simply stating that "it is his opinion" is not constructive and doesn't help anyone. He has some experience and it is worth knowing why he thought it would be better this way, instead of simply complain about JSLint and change to JSHint. Duscuting the WHY often brings me great knowledge. If you want to dump a good opportunity to learn by simply stating it's his opinion, that's your choice. – 7hi4g0 Dec 26 '13 at 19:53
  • Not sure what in my question deserves a downvote!?! A comment on that would be great. – 7hi4g0 Dec 26 '13 at 20:00
  • @DaggNabbit don't know, didn't try. This is for a personal project and I'm using JSLint to have a little experience with it. If my code passes a less permissive linter than I know it's good code, right? :D – 7hi4g0 Dec 26 '13 at 20:04
  • You know it's carefully-formatted code, at least ;) – Dagg Nabbit Dec 26 '13 at 20:52
  • 1
    JSHint allows the warning to be disabled with /*jslint latedef:false*/: http://stackoverflow.com/a/9512299/259 – David Sykes Mar 27 '14 at 15:21
  • Thank you for pointing out something many people seem to forget.. i.e: Why is this an error? Nothing but silence or "this guy says so" This question should be upvoted a lot.. – kiwicomb123 Nov 05 '17 at 02:08

2 Answers2

3

It is NOT an error (your code does work after all). The concern with this is that declaring function after it has been used decreases readibility of the code. Someone reading your code may think this function is declared somewhere in outer scope. This can be especially confusing, if you overwrite popular functions/constructors like Date

Mchl
  • 61,444
  • 9
  • 118
  • 120
  • 1
    I used error as a manner of speech. Thanks for your answer. I was imagining something like that :) – 7hi4g0 Dec 26 '13 at 19:56
0

Generally, if you're going to do what jshint/jslint say, and define functions before their use, then there's no overwhelming reason (other than aesthetic) to prefer function declarations over function expressions.

Here's my opinion: Declaring functions after they're used is bad, unless it's very clear that you're referring to a function that's declared in the same scope. This can either be a result of good naming or proximity.

For example, you're returning a reference to the declared function immediately before it's declared. Here, you've clarified the intent of your outer function, which is equally as important, and the reader knows they don't have to scan downward to see if there is additional code specific to the outer scope.

That said, I also think sprinkling function declarations amongst your outer scope's code of intent is also horrible for readability, but maybe I'm a terrible person.