defining functions

Discussion in 'Javascript' started by Denis McMahon, Nov 5, 2011.

  1. While I'm waiting for the faq to load so I can see if it says there in a
    manner that I can find, what's the difference between the function
    definition:

    var x = function(y)
    {
    // do something
    return;
    }

    and the function definition:

    function x(y)
    {
    // do something
    return;
    }

    and why might someone choose to use one form over the other when their
    function calls are of the form:

    x(y);

    Rgds

    Denis McMahon
     
    Denis McMahon, Nov 5, 2011
    #1
    1. Advertisements

  2. To be precise, it is necessary to use a /FunctionExpression/ if the function
    is to be defined in a /Block/ statement. Although several ECMAScript
    implementations, among them JavaScript 1.3, JScript 3.1.3510, JavaScriptCore
    525.13, Opera ECMAScript 5.02, and KJS 3.5.9, include(d) proprietary support
    for /FunctionDeclaration/ in a /Block/ statement (termed and dealt with as a
    "function statement"), such code is not portable and therefore best avoided.
    (Note that the braces of /Block/ statements are easily confused with the
    braces of a /FunctionBody/; this restriction and recommendation does _not_
    apply to the latter.)


    PointedEars
     
    Thomas 'PointedEars' Lahn, Nov 5, 2011
    #2
    1. Advertisements

  3. Denis McMahon

    J.R. Guest

    Hi,
    According to the excellent JavaScript Patterns book, by Stoyan Stefanov,
    Chapter 4 - Functions, section "Declarations Versus Expressions: Names
    and Hoisting" (p. 59):

    - Function declarations can only appear in 'program code', meaning
    inside of the bodies of other functions or in the global space. Their
    definitions cannot be assigned to variables or properties, or appear in
    function invocations as parameters;

    - the availability of the read-only name property of the function
    definition pattern. This property is not standard but available in many
    environments. In function declarations and named function expressions,
    the name property is defined. In anonymous function expressions, it
    depends on the implementation; it could be undefined (IE) or defined
    with an empty string (Firefox, WebKit) [...] The name property is useful
    when debugging code in Firebug or other debuggers. When the debugger
    needs to show you an error in a function, it can check for the presence
    of the name property and use it as an indicator. The name property is
    also used to call the same function recursively from within itself. If
    you were not interested in these two cases, then an unnamed function
    expression would be easier and less verbose.

    *And finally, the most important difference IMO lies in the hoisting
    behavior*:
    [...] all variables, no matter where in the function body they are
    declared, get hoisted to the top of the function behind the scenes. The
    same applies for functions because they are just objects assigned to
    variables. The only “gotcha†is that when using a function declaration,
    the definition of the function also gets hoisted, not only its
    declaration. Consider this snippet:

    // antipattern
    // for illustration only
    // global functions
    function foo() {
    alert('global foo');
    }

    function bar() {
    alert('global bar');
    }

    function hoistMe() {
    console.log(typeof foo); // "function"
    console.log(typeof bar); // "undefined"
    foo(); // "local foo"
    bar(); // TypeError: bar is not a function
    // function declaration:
    // variable 'foo' and its implementation both get hoisted

    function foo() {
    alert('local foo');
    }
    // function expression:
    // only variable 'bar' gets hoisted
    // not the implementation
    var bar = function () {
    alert('local bar');
    };
    }
    hoistMe();

    In this example you see that, just like with normal variables, the mere
    presence of foo and bar anywhere in the hoistMe() function moves them to
    the top, overwriting the global foo and bar. The difference is that
    local foo()’s definition is hoisted to the top and works fine; although
    it’s defined later. The definition of bar() is not hoisted, only
    its declaration. That’s why until the code execution reaches bar()’s
    definition, it’s undefined and not usable as a function (while still
    preventing the global bar() from being “seen†in the scope chain).

    I'd strongly suggest that you purchase and read this book carefully.

    Cheers,
    Joao Rodrigues (J.R.)
     
    J.R., Nov 5, 2011
    #3
  4. Depending on what you mean by "their definitions", the second sentence may
    be wrong. For the following is certainly possible:

    function x(y)
    {
    console.log(y);
    }

    var z = x;

    var o = {
    p: x
    };

    (function(f) { return f; })(o.p)(42);

    You would be correct if you said that a function declaration cannot appear
    right-hand side of an assignment operator or within an argument list of a
    function call. That is so simply because the parser is in Expression
    context there, and the FunctionDeclaration syntax is considered to be a
    named FunctionExpression there.
    In Microsoft JScript, which you mistakenly and misguidingly referred to as
    "IE", at least in version 5.6.6626, Function instances have no `name'
    property in any case.
    ^^^^^^^^
    I beg your pardon?
    Utter nonsense.
    That is oversimplifying talk; nothing is "hoisted" here. What really
    happens is that all declarations in source code are specified to happen
    before control reaches the first statement of the execution context.
    Variable instantiation adds a property to the ES 1 to 3 Variable Object,
    with the identifier of the variable or function as name [1]. In ES 5.x,
    this is described as Declaration Binding Instantiation, i. e. bindings added
    to a VariableEnvironment's Environment Record, instead, but it follows
    essentially the same pattern [2].
    I strongly suggest that you stop believing blindly in what book authors
    (anyone, really) say and start thinking for yourself. /Sapere aude!/


    HTH

    PointedEars
    ___________
    [1] Standard ECMA-262, "ECMAScript Language Specification", Edition 3 Final,
    section 10.1.3, "Variable Instantiation". Ecma International, Geneva,
    March 2000.
    [2] Standard ECMA-262, "ECMAScript Language Specification", 5.1 Edition,
    section 10.5, "Declaration Binding Instantiation". Ecma International,
    Geneva, June 2011.
     
    Thomas 'PointedEars' Lahn, Nov 7, 2011
    #4
  5. Denis McMahon

    J.R. Guest

    No, it is not.
    The book's author explains the term "hoisting" on page 15:

    "[...] For completeness, let’s mention that actually at the
    implementation level things are a little more complex. There are two
    stages of the code handling, where variables, function declarations, and
    formal parameters are created at the first stage, which is the stage of
    parsing and entering the context. In the second stage, the stage of
    runtime code execution, function expressions and unqualified identifiers
    (undeclared variables) are created. But for practical purposes, we can
    adopt the concept of hoisting, which is actually not defined by
    ECMAScript standard but is commonly used to describe the behavior."

    If you google for "variable hoisting +javascript", you'll see that the
    term has been used by some renowned JS developers (Kangax, Nicholas
    Zakas, Stoyan Stefanov, Dustin Diaz, Dmitry Soshnikov, etc.) as a
    simplification of the ECMAScript Language Specification.

    I stand my point: this is an excellent book, although there are some
    minor errors / typos in it the same way it happens to other excellent /
    good books. And praising a book / author has nothing to do with blind faith.
     
    J.R., Nov 13, 2011
    #5
  6. Yes, it is.
    What you don't seem to get is that I don't care that they define that term
    and I don't care who uses or seconds it. And neither should you. It is
    oversimplifying talk, thereby wrong and misleading to use it without the
    accompanying definition. That said, it is completely unnecessary to invent
    new terms here (but that appears to be a recurring theme nowadays, starting
    with "Ajax").

    The Specification's terms of "variable instantiation" or "declaration
    binding instantiation" are clear enough, and by contrast there really is an
    *authority* to which the definitions can be ascribed: the authors of the
    ECMAScript Language Specification, i. e. the Ecma International Technical
    Committee 39. (That is not to say they are infallible, but *they* *make*
    *the* *standard*.)
    Trying to propagate their misconceptions as being the absolute truth instead
    has.


    PointedEars
    --
    Not with javascript. Nonsense propagates like wildfire in this field.
    -- Richard Cornford, comp.lang.javascript, 2011-11-14
     
    Thomas 'PointedEars' Lahn, Nov 14, 2011
    #6
  7. Denis McMahon

    J.R. Guest

    Well, I don't agree with you.
    This time I must agree with you. Damn it!
    -- Richard Cornford, comp.lang.javascript, 2011-11-14

    Great Richard Cornford, always brilliant!
     
    J.R., Nov 14, 2011
    #7
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.