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. Advertising

  2. Richard Cornford wrote:

    > Denis McMahon wrote:
    >> [FunctionExpression vs. FunctionDeclaration]

    >
    > In terms of this style of function call there is no advantage of one
    > over the other.
    >
    > The advantages of one over the other are that the function declaration
    > is less code to write and the actual creation of the function object
    > will occur unconditionally upon entering the execution context in which
    > the declaration occurs. Assigning a function expression to a variable is
    > necessary if the function is to be created conditionally.


    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
    --
    Anyone who slaps a 'this page is best viewed with Browser X' label on
    a Web page appears to be yearning for the bad old days, before the Web,
    when you had very little chance of reading a document written on another
    computer, another word processor, or another network. -- Tim Berners-Lee
    Thomas 'PointedEars' Lahn, Nov 5, 2011
    #2
    1. Advertising

  3. Denis McMahon

    J.R. Guest

    On 05/11/2011 01:09, Denis McMahon wrote:
    > 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);


    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. J.R. wrote:

    > On 05/11/2011 01:09, Denis McMahon wrote:
    >> 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);

    >
    > 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;


    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.

    > - 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) [...]


    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.

    > *And finally, the most important difference IMO lies in the hoisting

    ^^^^^^^^
    > behavior*:

    ^^^^^^^^
    I beg your pardon?

    > [...] all variables, no matter where in the function body they are
    > declared, get hoisted to the top of the function behind the scenes.


    Utter nonsense.

    > The same applies for functions because they are just objects assigned to
    > variables.


    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'd strongly suggest that you purchase and read this book carefully.


    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.
    --
    realism: HTML 4.01 Strict
    evangelism: XHTML 1.0 Strict
    madness: XHTML 1.1 as application/xhtml+xml
    -- Bjoern Hoehrmann
    Thomas 'PointedEars' Lahn, Nov 7, 2011
    #4
  5. Denis McMahon

    J.R. Guest

    On 07/11/2011 10:26, Thomas 'PointedEars' Lahn wrote:

    >> *And finally, the most important difference IMO lies in the hoisting

    > ^^^^^^^^
    >> behavior*:

    > ^^^^^^^^
    > I beg your pardon?
    >
    >> [...] all variables, no matter where in the function body they are
    >> declared, get hoisted to the top of the function behind the scenes.

    >
    > Utter nonsense.


    No, it is not.

    >> The same applies for functions because they are just objects assigned to
    >> variables.

    >
    > 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].


    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'd strongly suggest that you purchase and read this book carefully.

    >
    > I strongly suggest that you stop believing blindly in what book authors
    > (anyone, really) say and start thinking for yourself. /Sapere aude!/
    >


    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.

    --
    Joao Rodrigues (J.R.)
    J.R., Nov 13, 2011
    #5
  6. J.R. wrote:

    > On 07/11/2011 10:26, Thomas 'PointedEars' Lahn wrote:
    >>> *And finally, the most important difference IMO lies in the hoisting

    >> ^^^^^^^^
    >>> behavior*:

    >> ^^^^^^^^
    >> I beg your pardon?
    >>
    >>> [...] all variables, no matter where in the function body they are
    >>> declared, get hoisted to the top of the function behind the scenes.

    >>
    >> Utter nonsense.

    >
    > No, it is not.


    Yes, it is.

    >>> The same applies for functions because they are just objects assigned to
    >>> variables.

    >>
    >> 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].

    >
    > The book's author explains the term "hoisting" on page 15:
    > […]


    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*.)

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

    >>
    >> I strongly suggest that you stop believing blindly in what book authors
    >> (anyone, really) say and start thinking for yourself. /Sapere aude!/

    >
    > 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.


    Trying to propagate their misconceptions as being the absolute truth instead
    has.


    PointedEars
    --
    > If you get a bunch of authors […] that state the same "best practices"
    > in any programming language, then you can bet who is wrong or right...

    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

    On 14/11/2011 16:49, Thomas 'PointedEars' Lahn wrote:
    > J.R. wrote:
    >
    >> On 07/11/2011 10:26, Thomas 'PointedEars' Lahn wrote:
    >>>> *And finally, the most important difference IMO lies in the hoisting
    >>> ^^^^^^^^
    >>>> behavior*:
    >>> ^^^^^^^^
    >>> I beg your pardon?
    >>>
    >>>> [...] all variables, no matter where in the function body they are
    >>>> declared, get hoisted to the top of the function behind the scenes.
    >>>
    >>> Utter nonsense.

    >>
    >> No, it is not.

    >
    > Yes, it is.


    Well, I don't agree with you.

    >
    >>>> The same applies for functions because they are just objects assigned to
    >>>> variables.
    >>>
    >>> 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].

    >>
    >> The book's author explains the term "hoisting" on page 15:
    >> […]

    >
    > 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*.)


    This time I must agree with you. Damn it!

    >> If you get a bunch of authors […] that state the same "best
    >> practices" in any programming language, then you can bet who is
    >> wrong or right...

    > Not with javascript. Nonsense propagates like wildfire in this field.

    -- Richard Cornford, comp.lang.javascript, 2011-11-14

    Great Richard Cornford, always brilliant!

    --
    Joao Rodrigues (J.R.)
    J.R., Nov 14, 2011
    #7
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Stylus Studio
    Replies:
    0
    Views:
    388
    Stylus Studio
    May 1, 2006
  2. Xiangliang Meng
    Replies:
    1
    Views:
    1,577
    Victor Bazarov
    Jun 21, 2004
  3. johny smith
    Replies:
    8
    Views:
    402
    Peter Koch Larsen
    Jul 2, 2004
  4. Harry Pehkonen
    Replies:
    8
    Views:
    315
    Christos TZOTZIOY Georgiou
    Sep 8, 2003
  5. Jimith87

    Defining functions

    Jimith87, Nov 20, 2003, in forum: Python
    Replies:
    3
    Views:
    319
    Tobias Pfeiffer
    Nov 20, 2003
Loading...

Share This Page