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

Re: [jslint] `this` in anonymous function without strict violation?

Expand Messages
  • Tom Worster
    this is just JSLint saving you time in detecting an ES5 strict mode error see http://is.gd/WCXyRm
    Message 1 of 14 , Sep 7, 2012
    • 0 Attachment
      this is just JSLint saving you time in detecting an ES5 strict mode error

      see http://is.gd/WCXyRm



      On 9/7/12 6:45 AM, "Felix E. Klee" <felix.klee@...> wrote:

      >That code gives a strict violation (due to presence of `this`):
      >
      > function f() {
      > 'use strict';
      > return this.x;
      > }
      >
      >That code doesn't:
      >
      > var f = function () {
      > 'use strict';
      > return this.x;
      > };
      >
      >Why the difference?
      >
      >
      >------------------------------------
      >
      >Yahoo! Groups Links
      >
      >
      >
    • Felix E. Klee
      ...
      Message 2 of 14 , Sep 19, 2012
      • 0 Attachment
        On Fri, Sep 7, 2012 at 1:21 PM, Tom Worster <fsb@...> wrote:
        > this is just JSLint saving you time in detecting an ES5 strict mode
        > error
        >
        > see http://is.gd/WCXyRm

        <url:https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Funct
        ions_and_function_scope/Strict_mode?redirectlocale=en-US&redirectslug=Ja
        vaScript%2FStrict_mode#.22Securing.22_JavaScript>

        Thanks for the link. I now read the article, and I understand that
        JSLint is just warning about a strict mode error. However, I do not
        understand why "function f()" is treated differently than "var f =
        function ()". Aren't the two statements equivalent? Or am I missing
        something?
      • douglascrockford
        ... People who are using the expression form are more likely to know what they are doing.
        Message 3 of 14 , Sep 19, 2012
        • 0 Attachment
          --- In jslint_com@yahoogroups.com, "Felix E. Klee" <felix.klee@...> wrote:
          >
          > On Fri, Sep 7, 2012 at 1:21 PM, Tom Worster <fsb@...> wrote:
          > > this is just JSLint saving you time in detecting an ES5 strict mode
          > > error
          > >
          > > see http://is.gd/WCXyRm
          >
          > <url:https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Funct
          > ions_and_function_scope/Strict_mode?redirectlocale=en-US&redirectslug=Ja
          > vaScript%2FStrict_mode#.22Securing.22_JavaScript>
          >
          > Thanks for the link. I now read the article, and I understand that
          > JSLint is just warning about a strict mode error. However, I do not
          > understand why "function f()" is treated differently than "var f =
          > function ()". Aren't the two statements equivalent? Or am I missing
          > something?


          People who are using the expression form are more likely to know what they are doing.
        • Tom Worster
          ... (i m an incompetent but) i see it as analogous to the difference between: f = and var f = i the latter, function f is clearly within the scope of the
          Message 4 of 14 , Sep 19, 2012
          • 0 Attachment
            On 9/19/12 4:47 PM, "Felix E. Klee" <felix.klee@...> wrote:

            >On Fri, Sep 7, 2012 at 1:21 PM, Tom Worster <fsb@...> wrote:
            >> this is just JSLint saving you time in detecting an ES5 strict mode
            >> error
            >>
            >> see http://is.gd/WCXyRm
            >
            ><url:https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Funct
            >ions_and_function_scope/Strict_mode?redirectlocale=en-US&redirectslug=Ja
            >vaScript%2FStrict_mode#.22Securing.22_JavaScript>
            >
            >Thanks for the link. I now read the article, and I understand that
            >JSLint is just warning about a strict mode error. However, I do not
            >understand why "function f()" is treated differently than "var f =
            >function ()". Aren't the two statements equivalent? Or am I missing
            >something?


            (i'm an incompetent but) i see it as analogous to the difference between:

            f =

            and

            var f =

            i the latter, function f is clearly within the scope of the strict mode
            function it appears in. no danger using this in there.

            and if that's wrong then i'll just declare that it's a good enough
            metaphor for me:)
          • Emmett Pickerel
            The function statement is evaluated at the top of the current scope, regardless of physical location. The function expression is evaluated at the same time as
            Message 5 of 14 , Sep 19, 2012
            • 0 Attachment
              The function statement is evaluated at the top of the current scope, regardless of physical location. The function expression is evaluated at the same time as any other expression would be. Obviously, there are other things you cannot do with the function expression, but that's the primary difference.

              In general, avoid the statement form. There's no good reason for it, and it's equivalent to having multiple var statements in a scope.



              On Sep 19, 2012, at 1:47 PM, "Felix E. Klee" <felix.klee@...> wrote:

              > On Fri, Sep 7, 2012 at 1:21 PM, Tom Worster <fsb@...> wrote:
              > > this is just JSLint saving you time in detecting an ES5 strict mode
              > > error
              > >
              > > see http://is.gd/WCXyRm
              >
              > <url:https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Funct
              > ions_and_function_scope/Strict_mode?redirectlocale=en-US&redirectslug=Ja
              > vaScript%2FStrict_mode#.22Securing.22_JavaScript>
              >
              > Thanks for the link. I now read the article, and I understand that
              > JSLint is just warning about a strict mode error. However, I do not
              > understand why "function f()" is treated differently than "var f =
              > function ()". Aren't the two statements equivalent? Or am I missing
              > something?
              >


              [Non-text portions of this message have been removed]
            • Felix E. Klee
              On Thu, Sep 20, 2012 at 4:52 AM, Emmett Pickerel ... I am aware of that. However, that s not what the error message is about. ... Like what?
              Message 6 of 14 , Sep 20, 2012
              • 0 Attachment
                On Thu, Sep 20, 2012 at 4:52 AM, Emmett Pickerel
                <emmett.thesane@...> wrote:
                > The function statement is evaluated at the top of the current scope,
                > regardless of physical location. The function expression is evaluated
                > at the same time as any other expression would be.

                I am aware of that. However, that's not what the error message is about.

                > Obviously, there are other things you cannot do with the function
                > expression, [...]

                Like what?
              • Doc Emmett Splendid
                Sorry, that was a typo. I meant to say there are other things you cannot do with the function *statement* . As for the error, to elaborate on what Douglas
                Message 7 of 14 , Sep 20, 2012
                • 0 Attachment
                  Sorry, that was a typo. I meant to say "there are other things you cannot do with the function *statement*".

                  As for the error, to elaborate on what Douglas said, that "People who are using the expression form are more likely to know what they are doing," this is one place where an arbitrary line was drawn for catching potential programming mistakes. While neither form could be used in place, he decided that the expression form was more likely to indicate the programmer intends to call it with a context.

                  Emmett


                  ________________________________
                  From: Felix E. Klee <felix.klee@...>
                  To: jslint_com@yahoogroups.com
                  Sent: Thursday, 20 September 2012, 0:59
                  Subject: Re: [jslint] `this` in anonymous function without strict violation?


                   
                  On Thu, Sep 20, 2012 at 4:52 AM, Emmett Pickerel
                  <emmett.thesane@...> wrote:
                  > The function statement is evaluated at the top of the current scope,
                  > regardless of physical location. The function expression is evaluated
                  > at the same time as any other expression would be.

                  I am aware of that. However, that's not what the error message is about.

                  > Obviously, there are other things you cannot do with the function
                  > expression, [...]

                  Like what?



                  [Non-text portions of this message have been removed]
                • Felix E. Klee
                  On Fri, Sep 21, 2012 at 12:05 AM, Doc Emmett Splendid ... To my knowledge, `function f` is just a shortcut for `var f = function`. I am unaware of any
                  Message 8 of 14 , Sep 21, 2012
                  • 0 Attachment
                    On Fri, Sep 21, 2012 at 12:05 AM, Doc Emmett Splendid
                    <emmett.thesane@...> wrote:
                    > Sorry, that was a typo. I meant to say "there are other things you
                    > cannot do with the function *statement*".

                    To my knowledge, `function f` is just a shortcut for `var f = function`.
                    I am unaware of any difference between both.

                    > While neither form could be used in place, he decided that the
                    > expression form was more likely to indicate the programmer intends to
                    > call it with a context.

                    That's how I understand the rationale as well. So, the code in question
                    is not actually a strict mode violation.
                  • John Hawkinson
                    ... The former is hoisted. --jhawk@mit.edu John Hawkinson
                    Message 9 of 14 , Sep 21, 2012
                    • 0 Attachment
                      > To my knowledge, `function f` is just a shortcut for `var f = function`.
                      > I am unaware of any difference between both.

                      The former is hoisted.

                      --jhawk@...
                      John Hawkinson
                    • Felix E. Klee
                      On Fri, Sep 21, 2012 at 10:33 AM, Felix E. Klee ... Aside from the difference you mentioned earlier, of course: The function statement is
                      Message 10 of 14 , Sep 21, 2012
                      • 0 Attachment
                        On Fri, Sep 21, 2012 at 10:33 AM, Felix E. Klee <felix.klee@...>
                        wrote:
                        > I am unaware of any difference between both.

                        Aside from the difference you mentioned earlier, of course: "The
                        function statement is evaluated at the top of the current scope,
                        regardless of physical location."

                        (never actively thought about this before)
                      • Alexandre Morgaut
                        ... I see 2 differences first, the hoisting one which is even more important in a conditional block // this code won t work as it might be expected if (a ===
                        Message 11 of 14 , Sep 21, 2012
                        • 0 Attachment
                          > On Fri, Sep 21, 2012 at 12:05 AM, Doc Emmett Splendid
                          > <emmett.thesane@...> wrote:
                          > To my knowledge, `function f` is just a shortcut for `var f = function`.
                          > I am unaware of any difference between both.

                          I see 2 differences

                          first, the hoisting one which is even more important in a conditional block

                          // this code won't work as it might be expected
                          if (a === true) {
                          function f() {
                          return b;
                          }
                          } else {
                          function f() {
                          return c;
                          }
                          }

                          second, the function name property may be empty

                          function f() { ... } // f.name === "f"
                          var f = function () { ... } // f.name === ""
                          var f = function f() { ... } // f.name === "f"

                          The function name is very important when you debug the code or do profiling on it when you have performance issues if you don't want to see only '<anonymous>' in your stack (or in the functions list with the time spent in them in the profiler).

                          That's why, in my code convention, I often appreciate to use the declarative syntax for the functions while I will also put them on the top on the scope as I do for the var declarations. When I use the expression syntax, I always take care to give the function a meaningful name wherever it is used (for scopes, foreach or event handlers, methods...)

                          ex:

                          var MyClass;

                          (function ScopeMyClass() {

                          MyClass = function MyClassConstructor() {

                          };

                          MyClass.prototype.method1 = function MyClass_method1(anArray) {

                          anArray.forEach(
                          function anArray_forEach(element) { .... }
                          );

                          };

                          }());


                          Note that Web Inspector started to show some meaningful names instead of <anonymous< in stacks (ex: MyClass.method1), but he just does it as best as he can, and the other debuggers doesn't do it for now.

                          Sometime you will use call() or apply() on functions to add a common non-inherited interface to some objects, or use the same function in methods of different classes, and then have a common function name in different contexts
                        • douglascrockford
                          ... There were famous websites that were depending on having functions with -this- bound to the global object, who then put use strict on the code. That code
                          Message 12 of 14 , Sep 21, 2012
                          • 0 Attachment
                            --- In jslint_com@yahoogroups.com, "Felix E. Klee" <felix.klee@...> wrote:
                            >
                            > On Fri, Sep 7, 2012 at 1:21 PM, Tom Worster <fsb@...> wrote:
                            > > this is just JSLint saving you time in detecting an ES5 strict mode
                            > > error
                            > >
                            > > see http://is.gd/WCXyRm
                            >
                            > <url:https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Funct
                            > ions_and_function_scope/Strict_mode?redirectlocale=en-US&redirectslug=Ja
                            > vaScript%2FStrict_mode#.22Securing.22_JavaScript>
                            >
                            > Thanks for the link. I now read the article, and I understand that
                            > JSLint is just warning about a strict mode error. However, I do not
                            > understand why "function f()" is treated differently than "var f =
                            > function ()". Aren't the two statements equivalent? Or am I missing
                            > something?


                            There were famous websites that were depending on having functions with -this- bound to the global object, who then put 'use strict' on the code. That code failed in ES5 browsers but passed JSLint.

                            The difficulty for JSLint is that strict mode's operation on -this- is dynamic, but JSLint's analysis is static. How how could I reliably distinguish the case where -this- is used properly in a method from where -this- is used improperly to bind the global object.

                            My observation was that competent programmers always used function expressions to produce methods, and that incompetent programmers always used the statement form to bind the global object.

                            So when you specify strict mode, JSLint expects you to write like a competent programmer. I know that is a burden for some of you, but that's the best I can do.
                          • Felix E. Klee
                            On Fri, Sep 21, 2012 at 3:48 PM, douglascrockford ... Why not enforce that with JSLint? It would be help enforcing consistent coding style in projects.
                            Message 13 of 14 , Oct 18, 2012
                            • 0 Attachment
                              On Fri, Sep 21, 2012 at 3:48 PM, douglascrockford
                              <douglas@...> wrote:
                              > competent programmers always used function expressions to produce methods

                              Why not enforce that with JSLint?

                              It would be help enforcing consistent coding style in projects.
                            Your message has been successfully submitted and would be delivered to recipients shortly.