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

Bugs with JSLint and global variables.

Expand Messages
  • pauanyu
    test = function () {}; self.test = function () {}; window.test = function () {}; test(); JSLint sees the first three lines as different, even though they are
    Message 1 of 13 , May 1 9:30 AM
    • 0 Attachment
      test = function () {};
      self.test = function () {};
      window.test = function () {};
      test();

      JSLint sees the first three lines as different, even though they are in fact the same. It also insists that test is undefined.
    • Jakob Kruse
      I believe that unless you are in a browser, ”test” would be undefined in this case. First example is missing a “var”, second and third defines
      Message 2 of 13 , May 1 9:53 AM
      • 0 Attachment
        I believe that unless you are in a browser, ”test” would be undefined in this case. First example is missing a “var”, second and third defines properties on specific objects.

        /Jakob

        From: jslint_com@yahoogroups.com [mailto:jslint_com@yahoogroups.com] On Behalf Of pauanyu
        Sent: 1. maj 2009 18:31
        To: jslint_com@yahoogroups.com
        Subject: [jslint] Bugs with JSLint and global variables.





        test = function () {};
        self.test = function () {};
        window.test = function () {};
        test();

        JSLint sees the first three lines as different, even though they are in fact the same. It also insists that test is undefined.


        [Non-text portions of this message have been removed]
      • pauanyu
        ... Yes, and there s an assume a browser option that specifies browser objects (like window). You also don t need a var to declare a global variable, but
        Message 3 of 13 , May 1 10:02 AM
        • 0 Attachment
          --- In jslint_com@yahoogroups.com, "Jakob Kruse" <kruse@...> wrote:
          >
          > I believe that unless you are in a browser, "test" would be undefined in this case. First example is missing a "var", second and third defines properties on specific objects.
          >
          > /Jakob

          Yes, and there's an "assume a browser" option that specifies browser objects (like window). You also don't need a var to declare a global variable, but that's an entirely different story.

          Declaring a global variable in JavaScript is exactly the same as setting a property on the window or window.self object. No difference.

          You can even try:
          var test = function () {};
          alert(test === window.test);

          The point is: window contains all the global variables. Attaching a property to the window object is no different from declaring a global variable. And JSLint should be aware of that.
        • Jakob Kruse
          Again, the ”assume a browser” option of JSLint, AFAIK, only means that you don’t have to explicitly define the global object “window” and others. It
          Message 4 of 13 , May 1 1:36 PM
          • 0 Attachment
            Again, the ”assume a browser” option of JSLint, AFAIK, only means that you don’t have to explicitly define the global object “window” and others. It does not imply logic that any global variable is a property of the window object. I know exactly what you mean, but JSLint does not. Nor should it. You should write your code more clearly, for instance by using “var” to declare a global variable, by using the “function” keyword to declare a global function, or by calling “window.test()” if you have declared the “test” function using “window.test = …”.

            Just my opinion.

            /Jakob

            From: jslint_com@yahoogroups.com [mailto:jslint_com@yahoogroups.com] On Behalf Of pauanyu
            Sent: 1. maj 2009 19:03
            To: jslint_com@yahoogroups.com
            Subject: Re: [jslint] Bugs with JSLint and global variables.





            --- In jslint_com@yahoogroups.com, "Jakob Kruse" <kruse@...> wrote:
            >
            > I believe that unless you are in a browser, "test" would be undefined in this case. First example is missing a "var", second and third defines properties on specific objects.
            >
            > /Jakob

            Yes, and there's an "assume a browser" option that specifies browser objects (like window). You also don't need a var to declare a global variable, but that's an entirely different story.

            Declaring a global variable in JavaScript is exactly the same as setting a property on the window or window.self object. No difference.

            You can even try:
            var test = function () {};
            alert(test === window.test);

            The point is: window contains all the global variables. Attaching a property to the window object is no different from declaring a global variable. And JSLint should be aware of that.


            [Non-text portions of this message have been removed]
          • Douglas Crockford
            ... What are you proposing, that JSLint not allow access to window and self when assuming a browser? I think that is a reasonable restriction. A better
            Message 5 of 13 , May 1 2:47 PM
            • 0 Attachment
              --- In jslint_com@yahoogroups.com, "pauanyu" <pcxunlimited@...> wrote:
              >
              > test = function () {};
              > self.test = function () {};
              > window.test = function () {};
              > test();
              >
              > JSLint sees the first three lines as different, even though they are
              > in fact the same. It also insists that test is undefined.

              What are you proposing, that JSLint not allow access to window and self when assuming a browser?

              I think that is a reasonable restriction. A better discipline is to allow definition of globals only with var and /*global*/.

              What say the rest of you?
            • Merlin
              ... I agree.
              Message 6 of 13 , May 1 3:57 PM
              • 0 Attachment
                --- In jslint_com@yahoogroups.com, "Douglas Crockford" <douglas@...> wrote:
                > A better discipline is to allow definition of globals only with var and /*global*/.
                >
                I agree.
              • santini.alberto
                ... Using JavaScript also in a server-side context, test , self.test and window.test are three different things. For me the actual behaviour is ok.
                Message 7 of 13 , May 1 4:04 PM
                • 0 Attachment
                  --- In jslint_com@yahoogroups.com, "Douglas Crockford" <douglas@...> wrote:
                  > What say the rest of you?
                  >

                  Using JavaScript also in a server-side context, "test", "self.test" and "window.test" are three different things.

                  For me the actual behaviour is ok.

                  Regards,
                  Alberto
                • pauanyu
                  ... No, my proposal is that since declaring a global variable with var is exactly the same as assigning a property to the window object, JSLint should be
                  Message 8 of 13 , May 1 9:07 PM
                  • 0 Attachment
                    --- In jslint_com@yahoogroups.com, "Douglas Crockford" <douglas@...> wrote:
                    >
                    > What are you proposing, that JSLint not allow access to window and self when assuming a browser?
                    >
                    > I think that is a reasonable restriction. A better discipline is to allow definition of globals only with var and /*global*/.
                    >
                    > What say the rest of you?
                    >

                    No, my proposal is that since declaring a global variable with var is exactly the same as assigning a property to the window object, JSLint should be capable of detecting that. If you feel that this is an unreasonable thing for JSLint to do, then I'll just shut up and let this issue go.
                  • Michael Lorton
                    Declaring a global variable with var is not the same as assigning a property to the window object. In a browser, the two actions have the same effect, but a.
                    Message 9 of 13 , May 1 9:53 PM
                    • 0 Attachment
                      Declaring a global variable with var is not the same as assigning a property to the window object. In a browser, the two actions have the same effect, but

                      a. not all Javascript is run in the browser;
                      b. there are many other cases where semantically equivalent statements are treated different by JSLint -- most pertinently, consider declaring a global variable versus not declaring it at all (the latter being perfectly legal but very ad form).

                      You might say that if the assume-a-browser flag is set, then JSLint should regard declaring a global variable with var as interchangeable with assigning a property to the window object -- but I think you might be wrong. Doing so would require JSLint to have a really deep level understanding of the browser's object model, in return for supporting a pretty confusing style of coding.

                      M.





                      ________________________________
                      From: pauanyu <pcxunlimited@...>
                      To: jslint_com@yahoogroups.com
                      Sent: Friday, May 1, 2009 9:07:27 PM
                      Subject: [jslint] Re: Bugs with JSLint and global variables.

                      --- In jslint_com@yahoogroups.com, "Douglas Crockford" <douglas@...> wrote:
                      >
                      > What are you proposing, that JSLint not allow access to window and self when assuming a browser?
                      >
                      > I think that is a reasonable restriction. A better discipline is to allow definition of globals only with var and /*global*/.
                      >
                      > What say the rest of you?
                      >

                      No, my proposal is that since declaring a global variable with var is exactly the same as assigning a property to the window object, JSLint should be capable of detecting that. If you feel that this is an unreasonable thing for JSLint to do, then I'll just shut up and let this issue go.



                      ------------------------------------

                      Yahoo! Groups Links



                      [Non-text portions of this message have been removed]
                    • crlender
                      ... Yes, you do. Without var , you re not creating a variable, but a property of the global object, which in the case of browsers is window (aka self). ...
                      Message 10 of 13 , May 2 1:30 AM
                      • 0 Attachment
                        --- In jslint_com@yahoogroups.com, "pauanyu" <pcxunlimited@...> wrote:
                        > You also don't need a var to declare a global variable, but that's
                        > an entirely different story.

                        Yes, you do. Without "var", you're not creating a variable, but a
                        property of the global object, which in the case of browsers is
                        window (aka self).

                        > Declaring a global variable in JavaScript is exactly the same as
                        > setting a property on the window or window.self object. No
                        > difference.
                        ...
                        > Attaching a property to the window object is no different from
                        > declaring a global variable.

                        None of this is correct. The lookup through the scope chain ends up
                        at the same place (which is what you example with the strict
                        comparison operator tested), but that doesn't mean that variables
                        and object properties are the same thing.

                        var a = 1;
                        window.b = 1;
                        delete a;
                        delete window.b;
                        console.log("a:", typeof a);
                        console.log("b:", typeof b);

                        Variables are handled differently, and have the DontDelete attribute
                        set (check the specs). Accessing a nonexistent variable results in
                        a ReferenceError, while accessing a nonexistent object property
                        returns undefined.


                        - Conrad
                      • Jordan
                        ... I know this is late to the game, and you ve already decided and restricted window usage. However, when coding for the web, I find window.alert() MUCH
                        Message 11 of 13 , Jun 18, 2009
                        • 0 Attachment
                          --- In jslint_com@yahoogroups.com, "Douglas Crockford" <douglas@...> wrote:
                          >
                          > --- In jslint_com@yahoogroups.com, "pauanyu" <pcxunlimited@> wrote:
                          > >
                          > > test = function () {};
                          > > self.test = function () {};
                          > > window.test = function () {};
                          > > test();
                          > >
                          > > JSLint sees the first three lines as different, even though they are
                          > > in fact the same. It also insists that test is undefined.
                          >
                          > What are you proposing, that JSLint not allow access to window and self when assuming a browser?
                          >
                          > I think that is a reasonable restriction. A better discipline is to allow definition of globals only with var and /*global*/.
                          >
                          > What say the rest of you?
                          >


                          I know this is late to the game, and you've already decided and restricted "window" usage. However, when coding for the web, I find "window.alert()" MUCH better than "alert()" et cetera.

                          The reason is, by explicitly specifying "window", I have informed the code's reader that I am coding for a browser, that I understand that "alert" is a browser-specific global function, AND I have one less instance of a scopeless (yet undeclared) variable. To me, using "window" implies that one is aware of global scope issues instead of ignorant of them.
                        • pauanyu
                          ... As an addendum to this, it has been recently decided that name is a non-writable global by default, with the intent to catch accidental globals. I offer
                          Message 12 of 13 , Jun 19, 2009
                          • 0 Attachment
                            --- In jslint_com@yahoogroups.com, "Jordan" <ljharb@...> wrote:
                            >
                            >
                            > I know this is late to the game, and you've already decided and restricted "window" usage. However, when coding for the web, I find "window.alert()" MUCH better than "alert()" et cetera.
                            >
                            > The reason is, by explicitly specifying "window", I have informed the code's reader that I am coding for a browser, that I understand that "alert" is a browser-specific global function, AND I have one less instance of a scopeless (yet undeclared) variable. To me, using "window" implies that one is aware of global scope issues instead of ignorant of them.
                            >

                            As an addendum to this, it has been recently decided that "name" is a non-writable global by default, with the intent to catch accidental globals.

                            I offer the solution of using "window.name" when you wish to use the global variable, and "name" when you wish to use the local variable. This is rather trickier with the restriction against "window".

                            This has the benefit of making it extremely obvious to everybody whether you are intending to use the global or local. This improves code readability, and helps to catch errors. We should make the distinction between globals and locals more obvious, not less.
                          • pauanyu
                            ... I gave some more thought to this. Right now, if you want to use the global name and local name , JSLint says you *must* put either var name; or
                            Message 13 of 13 , Jun 20, 2009
                            • 0 Attachment
                              --- In jslint_com@yahoogroups.com, "pauanyu" <pcxunlimited@...> wrote:
                              >
                              > As an addendum to this, it has been recently decided that "name" is a non-writable global by default, with the intent to catch accidental globals.
                              >
                              > I offer the solution of using "window.name" when you wish to use the global variable, and "name" when you wish to use the local variable. This is rather trickier with the restriction against "window".
                              >
                              > This has the benefit of making it extremely obvious to everybody whether you are intending to use the global or local. This improves code readability, and helps to catch errors. We should make the distinction between globals and locals more obvious, not less.
                              >

                              I gave some more thought to this. Right now, if you want to use the global "name" and local "name", JSLint says you *must* put either "var name;" or /*global name:true */ at the top of your code.

                              Why is this bad? Because JSLint now no longer checks if you accidentally leave off a var statement when you intended to use the local "name". It fails silently, causing errors. This is a serious mistake.

                              As pointed out, we need to make the distinction between globals and locals more obvious, not less. When both global and local are referred to by the same name, you have a hard time telling them apart, which causes confusion.

                              However, we don't want to just allow "window" again. After all, we banned it for a reason, right? Here is my solution.


                              You can freely use "window" to refer to *already-declared* global variables:

                              // These are okay:
                              window.name = 1;
                              window.onload = function () {};
                              window.addEventListener();


                              However! You cannot use "window" to create *new* global variables:

                              // This fails with the error "Use var to declare new globals":
                              window.foo = function () {};


                              Now, you can use "window.name" for global, and "name" for local. If somebody else reads your code, it is now extremely obvious whether you intended the global or local. This reduces confusion and increases maintainability. In addition, if you forget to use "var" to declare the local "name", JSLint will now give you an error! Before, it failed silently.

                              Lastly, because you cannot create new globals with "window", this removes the original problem (why we banned it in the first place). The ideal solution.

                              P.S. I chose to pick on "name" here, but it could easily be another global, like "top" or "status".
                            Your message has been successfully submitted and would be delivered to recipients shortly.