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

Re: Bugs with JSLint and global variables.

Expand Messages
  • 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 1 of 13 , May 1, 2009
    View Source
    • 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 2 of 13 , May 1, 2009
      View Source
      • 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 3 of 13 , May 2, 2009
        View Source
        • 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 4 of 13 , Jun 18, 2009
          View Source
          • 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 5 of 13 , Jun 19, 2009
            View Source
            • 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 6 of 13 , Jun 20, 2009
              View Source
              • 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.