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

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

Expand Messages
  • 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 1 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 2 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 3 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 4 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 5 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 6 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 7 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 8 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.