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

Re: [jslint] Re: Undefined variable

Expand Messages
  • Jakob Kruse
    Either I misunderstand you or you misunderstood me. I was talking about namespaces. I ll give an example: In file1.js: var My = {}; My.method = function() {
    Message 1 of 25 , May 29, 2009
    • 0 Attachment
      Either I misunderstand you or you misunderstood me.

      I was talking about namespaces. I'll give an example:

      In file1.js:

      var My = {};
      My.method = function() { ... };

      In file2.js

      var My = {};
      My.other_method = function() { ... };

      These are two files. Both declare some functionality. They both do so using the same namespace. They way they do so here, if you include them both, you will only get the functionality from the last one.

      The way you fix this (the simplest one I know of) is:

      file1.js:

      var My = My || {};
      My.method = function() { ... };

      file2.js:

      var My = My || {};
      My.other_method = function() { ... };

      Now include both files and you will get two methods defined. I fail to see a problem.

      /Jakob

      ----- Original Message -----
      From: sandyhead25
      [mailto:austin.cheney@...]
      To: jslint_com@yahoogroups.com
      Sent: Fri,
      29 May 2009 17:06:32 +0200
      Subject: [jslint] Re: Undefined variable


      > --- In jslint_com@yahoogroups.com, "Jakob Kruse" <kruse@...> wrote:
      > >
      > > Hasn't this all gotten a little far from the original problem?
      > >
      > > The way I understood it, it had to do with "namespaces". If you have two
      > javascript files that both declare some functionality in the same namespace,
      > and you're not sure if you'll be using one file, the other file, or both
      > files (or you are sure but all three cases exist in various parts of the
      > application), then you do need "special tricks" (i.e. not just creating the
      > namespace and putting stuff in it) to avoid the contents of the second file
      > removing everything declared by the first.
      > >
      > > The simple trick is to start both files like this:
      > >
      > > var Namespace = Namespace || {};
      > >
      > > No need to check if Namespace has already been declared, just use the
      > rather powerful 'or' operator.
      > >
      > > /Jakob
      > >
      [snip]
      >
      > In that case it is even more simple. If two named values exist within the
      > same scope the only that survives is the one that is declared last. If it
      > is a matter of functions competing for the same scope from different JS
      > files the only one that survives is the one that is in the file sourced last
      > into the HTML.
      >
      >
    • crlender
      ... 1) You said defined , not declared 2) How do you propose to test if a variable has been declared? (hint: you don t; you always know if it s been
      Message 2 of 25 , May 29, 2009
      • 0 Attachment
        --- In jslint_com@yahoogroups.com, "sandyhead25" <austin.cheney@...> wrote:
        >
        > > You mean declared, not defined (big difference).
        >
        > I meant exactly what I said. He should test if a variable has been
        > declared and not whether it has been defined.

        1) You said "defined", not "declared"
        2) How do you propose to test if a variable has been declared?
        (hint: you don't; you always know if it's been declared or not).

        > Scope is local to the object containing the variable declaration,
        > as a result the scope of a variable is chosen based upon which
        > object in it is declared in an object hierarchy. This is an
        > important distinction apart from considering variables as only
        > local to their object of instantiation for the sake of closures.

        There is only global and function scope in JavaScript. Saying "scope
        is local to an object" is incorrect.

        > > > var a, b,
        > > > c = (function () {
        > > > do or report something automatically
        > > > }());
        > > >
        > > > In that example JSLint would report var c as unused, which is not
        > > > accurate.
        > >
        > > Unless you use c inside the (function)(), or further down in the
        > > current scope, it definitely will be unused. What's the problem?
        >
        > You are wrong. The practice is called immediate invocation, and
        > JSLint has an option to enforce wrapping such practices in
        > parentheses. Any function that is logically reachable and properly
        > closed with an ending curly brace and immediately followed by a
        > parenthesis pair is executed immediately without regard for where
        > that function exists.

        That doesn't have anything to do with what I wrote. If you declare
        a variable and then don't use it, you get a warning.

        > Don't just take my word for it try it yourself. An example of this
        > is the 'it' function in my markupmin application available at
        > http://mailmarkup.org/prettydiff/prettydiff.html

        I don't have time to analyze all of that, but it looks like you're
        declaring a local variable called "it", which you don't use in its
        scope, leading to the (correct) JSLint warning. What's the point of
        this variable? And what's the point of that anonymous function there?
        You don't use it to introduce a new scope, and it doesn't return
        anything (meaning |it| will be assigned a value of |undefined|).
        None of this makes sense:

        function () {
        var ...,
        it = (function() {
        // some loop that doesn't return a value
        })();
        // note: |it| is only used once in this scope
        }

        You should drop both |it| and the anon function:

        function () {
        var ...;
        // some loop that doesn't return a value
        }


        - Conrad
      • stauren@yahoo.cn
        ... I think use var Testvar = Testvar in window ? window.Testvar || {}; is better, you won t miss Testvar even if it equals undefined. /stauren
        Message 3 of 25 , May 30, 2009
        • 0 Attachment
          --- In jslint_com@yahoogroups.com, Michael Lorton <mlorton@...> wrote:
          >
          > > you might try something like this...
          >
          >
          > > var Testvar = window.Testvar || {};
          >
          >
          > Not exactly like that, because
          >
          > window.Testvar = 0;
          > var Testvar = window.Testvar || {};
          >
          > Would result in Testvar being set to {}, not 0 as you would presumably want. Maybe
          >
          > var Testvar = (window.Testvar === undefined) || {};
          >

          I think use

          var Testvar = 'Testvar' in window ? window.Testvar || {};

          is better, you won't miss Testvar even if it equals undefined.

          /stauren

          >
          > M.
          >
          > --- In jslint_com@yahoogroups.com, Nagy Endre <forewer2000@> wrote:
          > >
          > > I'm trying to check if a variable is already defined and define if is not.
          > >
          > > If (Testvar === undefined) {
          > > � var Testvar = {};
          > > }
          > >
          > > JsLint say that Testvar was used before was defined.
          > > How can I check this in the right way?
          > >
          > >
          > >
          > >
          > >
          > >
          > > [Non-text portions of this message have been removed]
          > >
          >
          >
          >
          >
          > ------------------------------------
          >
          > Yahoo! Groups Links
          >
          >
          >
          > [Non-text portions of this message have been removed]
          >
        • stauren@yahoo.cn
          ... sorry, I mean var Testvar = Testvar in window ? window.Testvar : {}; /stauren
          Message 4 of 25 , May 30, 2009
          • 0 Attachment
            --- In jslint_com@yahoogroups.com, "stauren@..." <liuch.pku@...> wrote:
            >
            > --- In jslint_com@yahoogroups.com, Michael Lorton <mlorton@> wrote:
            > >
            > > > you might try something like this...
            > >
            > >
            > > > var Testvar = window.Testvar || {};
            > >
            > >
            > > Not exactly like that, because
            > >
            > > window.Testvar = 0;
            > > var Testvar = window.Testvar || {};
            > >
            > > Would result in Testvar being set to {}, not 0 as you would presumably want. Maybe
            > >
            > > var Testvar = (window.Testvar === undefined) || {};
            > >
            >
            > I think use
            >
            > var Testvar = 'Testvar' in window ? window.Testvar || {};
            >
            > is better, you won't miss Testvar even if it equals undefined.
            >
            > /stauren

            sorry, I mean
            var Testvar = 'Testvar' in window ? window.Testvar : {};

            /stauren

            >
            > >
            > > M.
            > >
            > > --- In jslint_com@yahoogroups.com, Nagy Endre <forewer2000@> wrote:
            > > >
            > > > I'm trying to check if a variable is already defined and define if is not.
            > > >
            > > > If (Testvar === undefined) {
            > > > � var Testvar = {};
            > > > }
            > > >
            > > > JsLint say that Testvar was used before was defined.
            > > > How can I check this in the right way?
            > > >
            > > >
            > > >
            > > >
            > > >
            > > >
            > > > [Non-text portions of this message have been removed]
            > > >
            > >
            > >
            > >
            > >
            > > ------------------------------------
            > >
            > > Yahoo! Groups Links
            > >
            > >
            > >
            > > [Non-text portions of this message have been removed]
            > >
            >
          • sandyhead25
            I have encountered this problem before on my company website. When two identical object names, including functions, exist in the same namespace the only one
            Message 5 of 25 , May 31, 2009
            • 0 Attachment
              I have encountered this problem before on my company website. When two identical object names, including functions, exist in the same namespace the only one that survives to execution is the one that is read into the interpreter last. This means if you have two functions declared with the same name, in the same scope, and each from a different file the only one that survives is the one in the file that sourced into the HTML page last. There are only two exceptions to this rule.

              The first exception to this rule of last only is if a named object exists, is requested for execution, and then redefined after that execution in a top to bottom evaluation of code fed into the interpreter.

              The second exception is if the code sourced in last exists in a file that is unreachable. Then of course the rule is never applied.

              As a result when more than one file is the cause of namespace confusion the solution is simple. He just has to look for the file included last in the HTML from top to bottom and left to right evaluation of the code by the HTML parser.

              --- In jslint_com@yahoogroups.com, "Jakob Kruse" <kruse@...> wrote:
              >
              > Either I misunderstand you or you misunderstood me.
              >
              > I was talking about namespaces. I'll give an example:
              >
              > In file1.js:
              >
              > var My = {};
              > My.method = function() { ... };
              >
              > In file2.js
              >
              > var My = {};
              > My.other_method = function() { ... };
              >
              > These are two files. Both declare some functionality. They both do so using the same namespace. They way they do so here, if you include them both, you will only get the functionality from the last one.
              >
              > The way you fix this (the simplest one I know of) is:
              >
              > file1.js:
              >
              > var My = My || {};
              > My.method = function() { ... };
              >
              > file2.js:
              >
              > var My = My || {};
              > My.other_method = function() { ... };
              >
              > Now include both files and you will get two methods defined. I fail to see a problem.
              >
              > /Jakob
              >
              > ----- Original Message -----
              > From: sandyhead25
              > [mailto:austin.cheney@...]
              > To: jslint_com@yahoogroups.com
              > Sent: Fri,
              > 29 May 2009 17:06:32 +0200
              > Subject: [jslint] Re: Undefined variable
              >
              >
              > > --- In jslint_com@yahoogroups.com, "Jakob Kruse" <kruse@> wrote:
              > > >
              > > > Hasn't this all gotten a little far from the original problem?
              > > >
              > > > The way I understood it, it had to do with "namespaces". If you have two
              > > javascript files that both declare some functionality in the same namespace,
              > > and you're not sure if you'll be using one file, the other file, or both
              > > files (or you are sure but all three cases exist in various parts of the
              > > application), then you do need "special tricks" (i.e. not just creating the
              > > namespace and putting stuff in it) to avoid the contents of the second file
              > > removing everything declared by the first.
              > > >
              > > > The simple trick is to start both files like this:
              > > >
              > > > var Namespace = Namespace || {};
              > > >
              > > > No need to check if Namespace has already been declared, just use the
              > > rather powerful 'or' operator.
              > > >
              > > > /Jakob
              > > >
              > [snip]
              > >
              > > In that case it is even more simple. If two named values exist within the
              > > same scope the only that survives is the one that is declared last. If it
              > > is a matter of functions competing for the same scope from different JS
              > > files the only one that survives is the one that is in the file sourced last
              > > into the HTML.
              > >
              > >
              >
            • sandyhead25
              ... Your example is invalid. You ended your function with })(); but it should have been }()); if you wishes to assert a function of immediate invocation. Try
              Message 6 of 25 , May 31, 2009
              • 0 Attachment
                --- In jslint_com@yahoogroups.com, "crlender" <crlender@...> wrote:
                >
                > --- In jslint_com@yahoogroups.com, "sandyhead25" <austin.cheney@> wrote:
                > >
                > > > You mean declared, not defined (big difference).
                > >
                > > I meant exactly what I said. He should test if a variable has been
                > > declared and not whether it has been defined.
                >
                > 1) You said "defined", not "declared"
                > 2) How do you propose to test if a variable has been declared?
                > (hint: you don't; you always know if it's been declared or not).
                >
                > > Scope is local to the object containing the variable declaration,
                > > as a result the scope of a variable is chosen based upon which
                > > object in it is declared in an object hierarchy. This is an
                > > important distinction apart from considering variables as only
                > > local to their object of instantiation for the sake of closures.
                >
                > There is only global and function scope in JavaScript. Saying "scope
                > is local to an object" is incorrect.
                >
                > > > > var a, b,
                > > > > c = (function () {
                > > > > do or report something automatically
                > > > > }());
                > > > >
                > > > > In that example JSLint would report var c as unused, which is not
                > > > > accurate.
                > > >
                > > > Unless you use c inside the (function)(), or further down in the
                > > > current scope, it definitely will be unused. What's the problem?
                > >
                > > You are wrong. The practice is called immediate invocation, and
                > > JSLint has an option to enforce wrapping such practices in
                > > parentheses. Any function that is logically reachable and properly
                > > closed with an ending curly brace and immediately followed by a
                > > parenthesis pair is executed immediately without regard for where
                > > that function exists.
                >
                > That doesn't have anything to do with what I wrote. If you declare
                > a variable and then don't use it, you get a warning.
                >
                > > Don't just take my word for it try it yourself. An example of this
                > > is the 'it' function in my markupmin application available at
                > > http://mailmarkup.org/prettydiff/prettydiff.html
                >
                > I don't have time to analyze all of that, but it looks like you're
                > declaring a local variable called "it", which you don't use in its
                > scope, leading to the (correct) JSLint warning. What's the point of
                > this variable? And what's the point of that anonymous function there?
                > You don't use it to introduce a new scope, and it doesn't return
                > anything (meaning |it| will be assigned a value of |undefined|).
                > None of this makes sense:
                >
                > function () {
                > var ...,
                > it = (function() {
                > // some loop that doesn't return a value
                > })();
                > // note: |it| is only used once in this scope
                > }
                >
                > You should drop both |it| and the anon function:
                >
                > function () {
                > var ...;
                > // some loop that doesn't return a value
                > }
                >
                >
                > - Conrad
                >

                Your example is invalid. You ended your function with })(); but it should have been }()); if you wishes to assert a function of immediate invocation. Try to execute this code and let me know what happens:

                "use strict";
                var a = 1, b = 2, c = 3,
                d = (function () {
                var z = (function () {
                var e = a + 3;
                alert(e + b + c);
                }());
                }());
                alert(a + b + c);

                According to your claim function d and z are unused and so only one alert will fire with a value of 6. JSLint will tell you function z is not used. However, z is used. I just tried this myself.

                I figured out the problem with the JSLint reporting. If a function of immediate invocation is contained by a function it will show as unused even if the parent function exists in the global space and is itself a function of immediately invocation, which is not accurate.
              • crlender
                ... sandyhead, it s not invalid. The parens around (function) aren t required at all, they are merely a convention to indicate to the reader that this is not
                Message 7 of 25 , May 31, 2009
                • 0 Attachment
                  --- In jslint_com@yahoogroups.com, "sandyhead25" <austin.cheney@...> wrote:
                  >
                  > --- In jslint_com@yahoogroups.com, "crlender" <crlender@> wrote:
                  ...
                  > > [..] it looks like you're
                  > > declaring a local variable called "it", which you don't use in its
                  > > scope, leading to the (correct) JSLint warning. What's the point of
                  > > this variable? And what's the point of that anonymous function there?
                  > > You don't use it to introduce a new scope, and it doesn't return
                  > > anything (meaning |it| will be assigned a value of |undefined|).
                  > > None of this makes sense:
                  > >
                  > > function () {
                  > > var ...,
                  > > it = (function() {
                  > > // some loop that doesn't return a value
                  > > })();
                  > > // note: |it| is only used once in this scope
                  > > }
                  > >
                  > > You should drop both |it| and the anon function:
                  > >
                  > > function () {
                  > > var ...;
                  > > // some loop that doesn't return a value
                  > > }
                  > >
                  > >
                  > > - Conrad
                  > >
                  >
                  > Your example is invalid. You ended your function with })(); but
                  > it should have been }()); if you wishes to assert a function of
                  > immediate invocation.

                  sandyhead, it's not invalid. The parens around (function) aren't
                  required at all, they are merely a convention to indicate to the
                  reader that this is not an ordinary function expression. You could
                  just as well write

                  var x = function () { /*code*/ }();

                  JSLint has an option to enforce this convention (a Good Thing, in my
                  opinion), but has recently changed where the parens should be placed.
                  I do not agree with this change (and said so in this group), but
                  there's not much I can do about it. There are a lot more people who
                  place the parens the way I do, just take a look at the major
                  libraries like Dojo, YUI, JQuery, or others - none of them use the
                  new JSLint-approved style. I think it's too restrictive to demand one
                  of the two styles, when the intention is perfectly clear with both.

                  > Try to execute this code and let me know what happens:
                  >
                  > "use strict";
                  > var a = 1, b = 2, c = 3,
                  > d = (function () {
                  > var z = (function () {
                  > var e = a + 3;
                  > alert(e + b + c);
                  > }());
                  > }());
                  > alert(a + b + c);

                  Ah. And now try the same thing, except do an 'alert(d)' in the last
                  line. See what I mean? Both (function)s are executed, of course, but
                  that's not the point. The point is that the *variables* d and z are
                  never used.

                  > According to your claim function d and z are unused

                  Neither d or z are functions. That's the problem.


                  - Conrad
                • Douglas Crockford
                  ... Variable z is in fact unused. The proof of that is that you can delete var z = from that program and the result will be exactly the same.
                  Message 8 of 25 , May 31, 2009
                  • 0 Attachment
                    --- In jslint_com@yahoogroups.com, "sandyhead25" <austin.cheney@...> wrote:
                    > "use strict";
                    > var a = 1, b = 2, c = 3,
                    > d = (function () {
                    > var z = (function () {
                    > var e = a + 3;
                    > alert(e + b + c);
                    > }());
                    > }());
                    > alert(a + b + c);
                    >
                    > According to your claim function d and z are unused and so only one
                    > alert will fire with a value of 6. JSLint will tell you function z
                    > is not used. However, z is used. I just tried this myself.

                    Variable z is in fact unused. The proof of that is that you can
                    delete "var z = " from that program and the result will be exactly
                    the same.
                  • sandyhead25
                    ... Is execution not an indication of use? I would think if something were properly executed it is used code by the interpreter even if that usage, or any
                    Message 9 of 25 , Jun 1, 2009
                    • 0 Attachment
                      > Ah. And now try the same thing, except do an 'alert(d)' in the last
                      > line. See what I mean? Both (function)s are executed, of course, but
                      > that's not the point. The point is that the *variables* d and z are
                      > never used.

                      Is execution not an indication of use? I would think if something were properly executed it is used code by the interpreter even if that usage, or any other usage, does not result in any restatement for execution in remaining logic.

                      Furthermore when function d from the example is alerted it returns undefined only because it returns nothing after it executes. This is equivalent to declaring a variable and not defining it. If a return and a quoted string are placed between the end of d and z then d alerts as a value. This is no indication that d is unused.
                    • sandyhead25
                      ... When I execute the program I am presented with a first alert displaying 9 and then a second alert displaying 6 . If I remove z from the program the
                      Message 10 of 25 , Jun 1, 2009
                      • 0 Attachment
                        > Variable z is in fact unused. The proof of that is that you can
                        > delete "var z = " from that program and the result will be exactly
                        > the same.
                        >

                        When I execute the program I am presented with a first alert displaying "9" and then a second alert displaying "6". If I remove z from the program the first alert will no longer be present, which is an alteration to the resultant execution even if all other code cannot see or feel that alteration.

                        This lack of connection implies that functions of immediate invocation contained as instantiation declarations within other objects have a special unique context until such functions are any way restated or reused outside their declaration. That special unique context would be largely meaningless if not for objects that contain closures and several immediate invocation functions as declarations using those closures after the closure variables are declared.
                      Your message has been successfully submitted and would be delivered to recipients shortly.