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

Re: [jslint] Re: Implied global or hoisted var

Expand Messages
  • Marcel Duran
    You could use: var foo, bar; foo = function () { bar(); }; bar = function () { foo(); }; Marcel ... -- Marcel Duran [Non-text portions of this message have
    Message 1 of 10 , Jul 27, 2010
    • 0 Attachment
      You could use:

      var foo, bar;

      foo = function () {
      bar();
      };

      bar = function () {
      foo();
      };

      Marcel

      On Tue, Jul 27, 2010 at 5:52 PM, bertbelder <bertbelder@...> wrote:

      >
      >
      >
      >
      > Allright. But what if I have two functions that mutually call each other
      > (that was when I ran into this)? Then there is always one that is
      > 'encountered' before it is defined.
      >
      > Furthermore, IMHO if JSLint isn't happy with a certain coding style, that's
      > what it should complain about -- instead of producing wrong statements about
      > the code.
      >
      >
      > --- In jslint_com@yahoogroups.com <jslint_com%40yahoogroups.com>, Mark
      > Volkmann <r.mark.volkmann@...> wrote:
      > >
      > > JSLint wants you to define functions before their first call is
      > encountered.
      > > While your code would work the way you haven't, it's considered better
      > style
      > > to change the order of your code.
      > >
      > > On Tue, Jul 27, 2010 at 4:52 PM, Bert Belder <bertbelder@...> wrote:
      > >
      > > >
      > > >
      > > > When linting this code:
      > > >
      > > > (function outer() {
      > > > var foo = function() {
      > > > bar();
      > > > };
      > > >
      > > > var bar = function() {
      > > > };
      > > >
      > > > foo();
      > > > })();
      > > >
      > > > JSLint gives me these warnings:
      > > >
      > > > Problem at line 3 character 5: 'bar' is not defined.
      > > > Implied global: bar 3
      > > > Unused variable: bar 1 outer
      > > >
      > > > I think all three warnings are wrong. Due to type hoisting the 'var
      > bar'
      > > > declaration applies to the entire scope of the 'outer' function, so
      > foo()
      > > > inherits 'bar' from 'outer'.
      > > >
      > > > Or am I missing something here?
      > > >
      > > > best regards,
      > > > Bert
      > > >
      > > >
      > > >
      > >
      > >
      > >
      > > --
      > > R. Mark Volkmann
      > > Object Computing, Inc.
      > >
      > >
      > > [Non-text portions of this message have been removed]
      > >
      >
      >
      >



      --
      Marcel Duran


      [Non-text portions of this message have been removed]
    • Cheney, Edward A SSG RES USAR USARC
      These suggestions are all wrong. The problem here is when a variable invoked and defined. You can use: function foo () { bar(); } function bar () { var a =
      Message 2 of 10 , Jul 27, 2010
      • 0 Attachment
        These suggestions are all wrong.

        The problem here is when a variable invoked and defined.

        You can use:

        function foo () {
        bar();
        }

        function bar () {
        var a = "1234";
        }

        In the previous example you will notice that function bar does not directly point to a call to function foo, because function foo directly calls to function bar. If function bar did directly have a call to function foo there would be an endless recursion.

        You will also notice that the functions are invoked using the "function" keyword directly and not with the "var" keyword. Invoking functions with the "function" moves the function to the top of the stack of the current parent so that function calls can exist at any place in the given scope.

        Functions invoked with the var command are treated just like every other variable. This means it must be declared before it is used or it will be both undefined and an implied global. This means the JSLint error output is not being a pain in the ass, but is reporting a valid error.

        Austin Cheney
        http://prettydiff.com/
      • Mark Volkmann
        Edward, Starting your reply with These suggestions are all wrong. is rude, especially when they are not. Here is the original code, modified so JSLint likes
        Message 3 of 10 , Jul 28, 2010
        • 0 Attachment
          Edward,

          Starting your reply with "These suggestions are all wrong." is rude,
          especially when they are not.

          Here is the original code, modified so JSLint likes as much of it as
          possible and including a couple of print statements so we can see if it
          works.

          (function outer() {
          var foo = function () {
          print('in foo');
          bar();
          };

          var bar = function () {
          print('in bar');
          };

          foo();
          }());

          JSLint has two complaints about this code.
          1) at line 4, 'bar' is not defined.
          2) at line 7, Too many var statements.

          Complaint #1 is eliminated by simply reversing the order of the function
          declarations.
          Marcel's suggestion to declare foo and bar before they are defined
          eliminates both issues in one shot.

          Also, you said JSLint is reporting a valid error, but the code runs just
          fine ... at least in Rhino.

          On Tue, Jul 27, 2010 at 10:40 PM, Cheney, Edward A SSG RES USAR USARC <
          austin.cheney@...> wrote:

          >
          >
          > These suggestions are all wrong.
          >
          > The problem here is when a variable invoked and defined.
          >
          > You can use:
          >
          > function foo () {
          > bar();
          > }
          >
          > function bar () {
          > var a = "1234";
          > }
          >
          > In the previous example you will notice that function bar does not directly
          > point to a call to function foo, because function foo directly calls to
          > function bar. If function bar did directly have a call to function foo there
          > would be an endless recursion.
          >
          > You will also notice that the functions are invoked using the "function"
          > keyword directly and not with the "var" keyword. Invoking functions with the
          > "function" moves the function to the top of the stack of the current parent
          > so that function calls can exist at any place in the given scope.
          >
          > Functions invoked with the var command are treated just like every other
          > variable. This means it must be declared before it is used or it will be
          > both undefined and an implied global. This means the JSLint error output is
          > not being a pain in the ass, but is reporting a valid error.
          >
          > Austin Cheney
          > http://prettydiff.com/
          >
          >



          --
          R. Mark Volkmann
          Object Computing, Inc.


          [Non-text portions of this message have been removed]
        • bertbelder
          I know that reversing the declaration order would fix the example code I posted. However the situation that caused to me run into this doesn t really allow
          Message 4 of 10 , Jul 28, 2010
          • 0 Attachment
            I know that reversing the declaration order would fix the example code I posted. However the situation that caused to me run into this doesn't really allow reversing declaration orders without making the code really unreadable. Let me explain.

            Suppose you have to load several pieces of data *asynchronously* (using ajax for example) where the next data source to be loaded depends on data loaded before. Let's say the function `ajax(url, callback)` is defined, that does an ajax request and calls the callback when the response arrives.
            Then you could write:

            var whatWereLookingFor;
            ajax('/some/url', function(result) {
            ...
            ajax('/some/other/' + result.x, function(result) {
            ...
            ajax('/xyz/' + result.bar, function(result) {
            ...
            ajax('/bar/' + result.id, function(result) {
            // Woohoo we got it
            whatWereLookingFor = result;
            });
            });
            });
            });

            But that's terribly readable. So I was trying to write:

            function loadSome() {
            ajax("/some/url", loadOther);
            }
            function loadOther(result) {
            ajax("/some/other/" + result.x, loadFoo);
            }
            function loadFoo(result) {
            ajax("/xyz/" + result.bar, loadBar);
            }
            function loadBar(result) {
            ...
            }

            But JSLint doesn't eat that.

            The suggestion to reverse declaration order would solve the JSLint error, but then the function that is called last would be defined first, which I think would make the code confusing to a reader.

            The other solution would be to put a statement like
            var loadSome, loadOther, loadFoo, loadBar at the start of the function but that clutters my code with unnecessary statements, besides requiring me to keep the var statement in sync with the functions actually defined.

            So, any suggestions here?

            I don't really mind that JSLint complains when encountering a function call before the function is defined. But I would be very happy if it would just say that, and not mess up the implied globals list with variables that are NOT global.

            - Bert
          • Michael
            ... Bert; You re making a bunch of assumptions about your code. In the future you might try to make some changes that will make your code wrong. Imagine in
            Message 5 of 10 , Jul 28, 2010
            • 0 Attachment
              On Wed, Jul 28, 2010 at 8:44 AM, bertbelder <bertbelder@...> wrote:

              >
              >
              > I know that reversing the declaration order would fix the example code I
              > posted. However the situation that caused to me run into this doesn't really
              > allow reversing declaration orders without making the code really
              > unreadable. Let me explain.
              >
              > Suppose you have to load several pieces of data *asynchronously* (using
              > ajax for example) where the next data source to be loaded depends on data
              > loaded before. Let's say the function `ajax(url, callback)` is defined, that
              > does an ajax request and calls the callback when the response arrives.
              > Then you could write:
              >
              > var whatWereLookingFor;
              > ajax('/some/url', function(result) {
              > ...
              > ajax('/some/other/' + result.x, function(result) {
              > ...
              > ajax('/xyz/' + result.bar, function(result) {
              > ...
              > ajax('/bar/' + result.id, function(result) {
              > // Woohoo we got it
              > whatWereLookingFor = result;
              > });
              > });
              > });
              > });
              >
              > But that's terribly readable. So I was trying to write:
              >
              > function loadSome() {
              > ajax("/some/url", loadOther);
              > }
              > function loadOther(result) {
              > ajax("/some/other/" + result.x, loadFoo);
              > }
              > function loadFoo(result) {
              > ajax("/xyz/" + result.bar, loadBar);
              > }
              > function loadBar(result) {
              > ...
              > }
              >
              > But JSLint doesn't eat that.
              >
              > The suggestion to reverse declaration order would solve the JSLint error,
              > but then the function that is called last would be defined first, which I
              > think would make the code confusing to a reader.
              >
              > The other solution would be to put a statement like
              > var loadSome, loadOther, loadFoo, loadBar at the start of the function but
              > that clutters my code with unnecessary statements, besides requiring me to
              > keep the var statement in sync with the functions actually defined.
              >
              > So, any suggestions here?
              >
              > I don't really mind that JSLint complains when encountering a function call
              > before the function is defined. But I would be very happy if it would just
              > say that, and not mess up the implied globals list with variables that are
              > NOT global.
              >
              > - Bert
              >
              Bert;

              You're making a bunch of assumptions about your code. In the future you
              might try to make some changes that will make your code wrong. Imagine in
              your example:

              (function outer() {
              var foo = function() {
              bar();
              };

              if (true) {
              return;
              }

              var bar = function() {
              };

              foo();
              })();

              Suddenly your variable does become global. JSLint recommends you define all
              your variables at the top of each scope, so this kind of thing won't happen.
              JSLint will hurt your feelings, but it makes your code better.


              [Non-text portions of this message have been removed]
            • bertbelder
              ... Erm, I don t see it. What becomes global then?
              Message 6 of 10 , Jul 28, 2010
              • 0 Attachment
                > You're making a bunch of assumptions about your code. In the future you
                > might try to make some changes that will make your code wrong. Imagine in
                > your example:
                >
                > (function outer() {
                > var foo = function() {
                > bar();
                > };
                >
                > if (true) {
                > return;
                > }
                >
                > var bar = function() {
                > };
                >
                > foo();
                > })();
                >
                > Suddenly your variable does become global. JSLint recommends you define all
                > your variables at the top of each scope, so this kind of thing won't happen.

                Erm, I don't see it. What becomes global then?
              • Michael
                ... beyond confusing if you have it also defined in the global scope. [Non-text portions of this message have been removed]
                Message 7 of 10 , Jul 28, 2010
                • 0 Attachment
                  On Wed, Jul 28, 2010 at 9:07 AM, bertbelder <bertbelder@...> wrote:

                  >
                  >
                  > > You're making a bunch of assumptions about your code. In the future you
                  > > might try to make some changes that will make your code wrong. Imagine in
                  > > your example:
                  > >
                  > > (function outer() {
                  > > var foo = function() {
                  > > bar();
                  > > };
                  > >
                  > > if (true) {
                  > > return;
                  > > }
                  > >
                  > > var bar = function() {
                  > > };
                  > >
                  > > foo();
                  > > })();
                  > >
                  > > Suddenly your variable does become global. JSLint recommends you define
                  > all
                  > > your variables at the top of each scope, so this kind of thing won't
                  > happen.
                  >
                  > Erm, I don't see it. What becomes global then?
                  >
                  > You're right, I need more coffee. It becomes undefined due to hoisting, but
                  beyond confusing if you have it also defined in the global scope.


                  [Non-text portions of this message have been removed]
                Your message has been successfully submitted and would be delivered to recipients shortly.