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

Re: [jslint] option.undef

Expand Messages
  • Dominic Mitchell
    ... I m not bothered by this — it seems like a very sensible idea. -Dom [Non-text portions of this message have been removed]
    Message 1 of 9 , Dec 2, 2009
    • 0 Attachment
      On Wed, Dec 2, 2009 at 9:24 PM, 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?
      >

      I'm not bothered by this — it seems like a very sensible idea.

      -Dom


      [Non-text portions of this message have been removed]
    • 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 2 of 9 , Dec 2, 2009
      • 0 Attachment
        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 3 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 4 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 5 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 6 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 7 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 8 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.