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

Re: option.undef

Expand Messages
  • Aseem
    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,
    Message 1 of 9 , Dec 2, 2009
      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

      --- In jslint_com@yahoogroups.com, "Douglas Crockford" <douglas@...> wrote:
      >
      > I am thinking to remove the Disallow undefined variables. I added the option originally to make the transition easier for people with sloppy code. But that was years ago, and it is clear that disallowing undefined variables is simply the right thing. Would anyone be bothered by losing the ability to turn it off?
      >
    • 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 2 of 9 , Dec 2, 2009
        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 3 of 9 , Dec 3, 2009
          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 4 of 9 , Dec 3, 2009
            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 5 of 9 , Dec 4, 2009
              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 6 of 9 , Dec 4, 2009
                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 7 of 9 , Dec 4, 2009
                  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.