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

Re: option.undef

Expand Messages
  • pauanyu
    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
    Message 1 of 9 , Dec 2, 2009
    • 0 Attachment
      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.

      --- In jslint_com@yahoogroups.com, "Aseem" <aseem.kishore@...> wrote:
      >
      > I think the intention is right, but to be honest, I've turned it off on a few occasions as a workaround to allow code to be in a different order.
      >
      > By default, JSLint requires variables to be declared before they're used. That makes sense in general, but there are times where helper functions are better off lower in the file, physically.
      >
      > function SomeClass() {
      > // ...
      > helperFunction1();
      > helperFunction2();
      > }
      >
      > function helperFunction1() {
      > // ...
      > }
      >
      > function helperFunction2() {
      > // ...
      > }
      >
      > To me, that code is just fine and readable. But it fails JSLint with undef set to true.
      >
      > In this case, we could simply order the functions differently. If the helper functions are purely stand-alone, sure. But in many cases, they depend on the semantics of SomeClass, e.g. its properties. So it makes more sense to put them below the SomeClass logic.
      >
      > Another way of writing it, aside from ordering it differently, to not fail would be something like this.
      >
      > var helperFunction1, helperFunction2;
      >
      > function SomeClass() {
      > // ...
      > helperFunction1();
      > helperFunction2();
      > }
      >
      > helperFunction1 = function () {
      > // ...
      > }
      >
      > helperFunction2 = function () {
      > // ...
      > }
      >
      > But I haven't seen any added benefit to that style. If you're nitpicking, that in fact increases code size. But more importantly, I don't think it increases readability or anything like that.
      >
      > So as a temporary workaround, I've been setting undef to false after verifying that I'm not referencing any truly undefined variables.
      >
      > Aseem
    • Tim Beadle
      2009/12/3 pauanyu ... That sounds like a good idea - it would help people transition (I ve done some of that to scripts I ve taken
      Message 2 of 9 , Dec 3, 2009
      • 0 Attachment
        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
      • 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 3 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 4 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 5 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 6 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.