Loading ...
Sorry, an error occurred while loading the content.

Re: [jslint] Re: option.undef

Expand Messages
  • Stefan Weiss
    ... Nor will it in the first example. Function declarations are hoisted, which means that bar is guaranteed to be available before the first statement in a
    Message 1 of 9 , Dec 4, 2009
    • 0 Attachment
      On 03/12/09 21:32, Aseem wrote:
      > But I've been meaning to ask (and this is a good time to), what's
      > really wrong with referencing functions *inside* a function body?
      >
      > I can see why this feels wrong:
      >
      > bar();
      > function bar () {
      > // ...
      > }
      >
      > But I don't see why this is wrong:
      >
      > function foo () {
      > bar();
      > }
      > function bar () {
      > // ...
      > }
      >
      > In this case, bar() will never be called before it's truly defined.

      Nor will it in the first example. Function declarations are hoisted,
      which means that 'bar' is guaranteed to be available before the first
      statement in a script is executed.

      > In a way, it's backwards to require declarations before references.

      It can be inconvenient, too. I've had a few situations where circular
      dependencies between functions caused JSLint to emit "used before
      defined" warnings, but there was no way to resolve it by reordering
      function declarations alone. In the end, I used a function expression
      ('var foo = function () {...}') to break the cycle and work around the
      warnings, but it did make the script harder to read. It could be argued
      that circular dependencies aren't good style, but they're pretty common
      in event-based systems with more than one point of entry.

      Another problem with requiring a certain order for function declarations
      is that this often reverses the logical flow. For example:

      function fetchFoo() {
      ajaxGet("abc", receiveFoo);
      }

      function receiveFoo(response) {
      return response.foo;
      }

      Logically, "receive" follows "fetch", but the "undef" option requires
      the declaration order to be inverted. In the same way, "undef" can
      sometimes prevent the grouping or clustering of similar functions in a
      script.
      pauanyu's "Allow using a function before it was defined" would be nice
      to have, but I'm not sure if's feasible to add it. Unless I'm missing
      something, it would effectively require JSLint to

      a) do two consecutive runs in each scope, or
      b) to "remember" any calls to undeclared functions, and issue the
      warning at the end.


      cheers,
      stefan
    • Aseem
      Good post, I agree. Just a quick note -- ... Yes, this will work: bar(); function bar () { // ... } But I said it feels wrong, because in terms of
      Message 2 of 9 , Dec 4, 2009
      • 0 Attachment
        Good post, I agree. Just a quick note --

        > > In this case, bar() will never be called before it's truly defined.
        >
        > Nor will it in the first example. Function declarations are hoisted,
        > which means that 'bar' is guaranteed to be available before the first
        > statement in a script is executed.

        Yes, this will work:

        bar();
        function bar () {
        // ...
        }

        But I said it "feels" wrong, because in terms of readability, it's not obvious that it works. A new Javascript developer might consider it a bug and try to "fix" it.

        Incidentally, it's vulnerable to breaking if the function declaration is tweaked:

        bar();
        var bar = function () {
        // ...
        };

        That's why I understand the intent of the option, but in general, I agree with you that it's a very inconvenient warning that often makes scripts *harder* to read.

        I was mainly differentiating between my two examples because if bar() is called from within another function, it no longer seems "wrong" in any language, to any developer, because it's clear that bar() isn't being called immediately. I.e. it's no longer top-down programming.

        Aseem
      • Stefan Weiss
        Hello Aseem. I agree with your post, except for one nitpick: ... That isn t a function declaration, so it won t be hoisted, and it won t be available at
        Message 3 of 9 , Dec 4, 2009
        • 0 Attachment
          Hello Aseem.

          I agree with your post, except for one nitpick:

          On 04/12/09 19:09, Aseem wrote:
          > Incidentally, it's vulnerable to breaking if the function declaration is tweaked:
          >
          > bar();
          > var bar = function () {
          > // ...
          > };

          That isn't a function declaration, so it won't be hoisted, and it won't
          be available at runtime. It's a function *expression*.

          ACK, otherwise.

          cheers,
          stefan
        Your message has been successfully submitted and would be delivered to recipients shortly.