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

[jslint] Re: option.undef

Expand Messages
  • Aseem
    That will definitely work for the meantime. But I ve been meaning to ask (and this is a good time to), what s really wrong with referencing functions *inside*
    Message 1 of 9 , Dec 3, 2009
    • 0 Attachment
      That will definitely work for the meantime.

      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.

      In a way, it's backwards to require declarations before references. We went past strict top-down programming a long time ago.

      Just curious what your thoughts are. Thanks,

      Aseem

      --- In jslint_com@yahoogroups.com, Tim Beadle <tim.beadle@...> wrote:
      >
      > 2009/12/3 pauanyu <pcxunlimited@...>
      > > How about changing the "Disallow undefined variables" to "Allow using
      > > a function before it was defined"? That would handle Aseem's use-case
      > > while still forbidding undefined variables.
      >
      > That sounds like a good idea - it would help people transition (I've
      > done some of that to scripts I've taken over from someone else) in a
      > similar way to the original option.undef.
      >
      > Cheers,
      >
      > Tim
      >
    • 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 2 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 3 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 4 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.