defining functions

D

Denis McMahon

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
 
T

Thomas 'PointedEars' Lahn

Richard said:
Denis said:
[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
 
J

J.R.

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

Thomas 'PointedEars' Lahn

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

J.R.

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

Thomas 'PointedEars' Lahn

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

J.R.

J.R. said:
*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!
 

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. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,734
Messages
2,569,441
Members
44,832
Latest member
GlennSmall

Latest Threads

Top