Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

defining functions

17 views
Skip to first unread message

Denis McMahon

unread,
Nov 4, 2011, 11:09:18 PM11/4/11
to
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

Richard Cornford

unread,
Nov 5, 2011, 12:35:38 AM11/5/11
to
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;
> }

That is not a function definition, in ECMAScript terminology (so best
not called one). It is a variable declaration with assignment, where the
value being assigned is the result of evaluating a function expression.

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

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.

My position is that it is clearer (e.i. the textual distinction server
to add information to the source code by highlighting a real
distinction) and more direct to use a proper function declaration in all
circumstance where the result needs to be referred to by name and that
is practical. It is a position that appears to be unfashionable at
present, but for no apparent good reason.

Richard.

Thomas 'PointedEars' Lahn

unread,
Nov 5, 2011, 9:46:12 AM11/5/11
to
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

J.R.

unread,
Nov 5, 2011, 5:19:48 PM11/5/11
to
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.)

Thomas 'PointedEars' Lahn

unread,
Nov 7, 2011, 7:26:44 AM11/7/11
to
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

J.R.

unread,
Nov 13, 2011, 6:39:17 PM11/13/11
to
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.)

Thomas 'PointedEars' Lahn

unread,
Nov 14, 2011, 1:49:54 PM11/14/11
to
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

J.R.

unread,
Nov 14, 2011, 2:00:18 PM11/14/11
to
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.)
0 new messages