-Lost wrote:
Richard Cornford wrote:
>On Jan 31, 1:20 pm, Douglas Crockford wrote:
>>optimistx wrote:
<snip>
>>>(foo=function(){
alert('I am foo');
})();
instead of
bar=function(){
alert('I am bar');
}();
Is there a reason for this? Is there a difference?
There is no advantage to the first form.
It might be regarded as a shorter (and theoretically fractionally
faster) version of:-
foo = function(){ alert('I am foo');};
foo();
That is what I thought (after seeing it in some of your code).
>That is, assigning a function that you intend to call later
but at a point where you also want to call it immediately.
Its less than clear source code probably still mitigates
against any advantage that may follow form not doing that in
two statements.
>>I suspect that it was written by
someone who had seen
(function () {
alert('I am anonymous');
})();
and copied the pattern without understanding it.
<snip>
Given that the second example assigns the undefined value to
the - bar - variable to no apparent advantage there does seem
to be a failure to understand somewhere.
I am not entirely sure of its relevance, but:
http://subsimple.com/bookmarklets/ti...#Encapsulation
...explained it as a way of avoiding "void" in your code.
The context of that 'explanation' is the writing of bookmarklets. It
should not be taken as saying anything much for the general context of
javascript authoring (and would be seriously misleading if read in that
way).
I also do not totally understand its real-world use either.
There is virtually zero "real-world" use for the - void - operator.
That is, I see the code, I realize it is supposed to do
the same thing as void,
The - void - operator evaluates its Expression operand and then evaluates
its expression to the undefined value. That had nothing to do with the
inline execution of function expressions (except the coincidence that if
in such an expression the function object does not explicitly return
another value it will return the undefined value by default, and so the
whole CallExpresion's value will be the undefined value returned from the
function call).
but fail to see how or where you would use it. That
is just due to inexperience on my part though.
Probably.
The way I *thought* it should work is for example when assigning a
function to a link's onclick event. Like:
(function blah() { document.bgColor = 'blue'; })
<a href="" onclick="blah();">turn blue</a>
If you are referring to your 'blah' function (which is officially
unreferenceable as wrapping it in parenthesise makes it a
FunctionExpression with optional Identifier, rather than a
FunctionDeclaration, and so the Identifier 'blah' _should_ only be a
reference to that function object from within that function), then it is
_not_ being assigned to any link's - onclick - event.
When a browser sees the value of an intrinsic event attribute in an
(x)HTML element's tag it takes that value and uses it as the body code
for a function it creates internally and assigned to corresponding
property of the Element's representation in the DOM. So given:-
onclick="blah();"
- the browser does the equivalent of:-
LinkElementRef.onclick = function(event){
blah();
};
- internally (except that in reality some do some scope chain
augmentation and the - event - parameter is not (necessarily) used in
browsers following IE's event model).
So 'blah' is not assigned to the onclick event handler of a link, it is
called from the body of the function that the browser creates and
assigned to the onclick handler for the link.
Above, I thought surrounding your function with ()s made it
the same as:
function blah() { document.bgColor = 'blue'; }
This is a FunctionDeclaration, and so the 'blah' function should be
available globally (assuming a global context for the declaration).
<a href="" onclick="blah(); return false;">turn blue</a*OR*
For which the browser does:-
LinkElementRef.onclick = function(event){
blah();
return false;
};
<a href="" onclick="void(blah());">turn blue</a>
For which the browser does:-
LinkElementRef.onclick = function(event){
void (blah());
};
In which the - void - operator is pointless because nothing is done with
the result of the - void - operation, so its value is of no significance
anyway, and the - blah - function has no return statement so its return
value is the default undefined value. The evaluation goes:-
1. Evaluate the CallExpression (call the function and use its return
value as the evaluated result of the CallExpression), the result is the
undefined value.
2. Evaluate the grouped expression (the parenthesise that surround the
CallExpression), the result is the result of the CallExpression, the
undefined value.
3. Evaluate the - void - expression, by taking the result of the grouped
expression (the undefined value), discarding it and using the undefined
value it its place.
4. Discard that value and return form the function call.
This is not the case though.
blah is undefined when I surround it with ()s.
When you put parentheses around the code you make what was a
FunctionDeclaration into a FunctionExpression (with optional Identifier),
because a FunctionDeclaration cannot appear in an Expression context and
the subject of the grouping operators must be an Expression. However, if
you had tried that in IE the result of the well-known bug may have been
to mislead you into believing that you could still reference 'blah'.
Long story short, I do not understand the "function trick."
Trying to book mark let related 'explanations' to the general javascript
context will not be useful.
The only thing I *think* I understand is what I saw in your code.
var something = (function blah() { ...; return
somethingAboutBlah; })();
*OR* without the variable declaration.
You have never seen that in my code. I would not use the optional
Identifier with a FunctionExpression (at all, but particularly with a
function that may as well be anonymous).
It'd be nice if I could understand this more easily, but
my brain does not work that way. Yay for me.
All computer programming is the application of mechanical logic.
Everything involved can be precisely understood, in every detail, by
anyone rational, given time.
Richard.