From: Jorge on
<html><head></head><body><script>

(function () {
var watch = "Hola !";
(function f () { alert(watch) })();
alert(typeof f);
})();

</script></body></html>

This yields:

Safari : "Hola !", "undefined".
FireFox : "function () watch { [native code] }", "undefined"

Could you (kindly, please) tell me why :

1.- FF turns watch into a native function.
2.- f remains undefined.

TIA,
--Jorge.
From: Henry on
On May 7, 10:19 am, Jorge wrote:
> <html><head></head><body><script>
>
> (function () {
> var watch = "Hola !";
> (function f () { alert(watch) })();
> alert(typeof f);
>
> })();
>
> </script></body></html>
>
> This yields:
>
> Safari : "Hola !", "undefined".
> FireFox : "function () watch { [native code] }", "undefined"
>
> Could you (kindly, please) tell me why :
>
> 1.- FF turns watch into a native function.
> 2.- f remains undefined.

JavaScript(tm) objects have - watch - and - unwatch - methods (as an
aid to debugging). When a Function Expression is provided with the
optional Identifier (your 'f' in this case) the specified behaviour is
to create the corresponding function object with an additional object
at the top of the scope chain that is referred to by the function's
internal [[Scope]] property and give that object a name which
corresponds with the Identifier and a value that refers to the
function object. A side effect of this is that when the function is
executed it has an ordinary javascript object on its scope chain and
so all Identifiers used within the function that correspond with the
named properties of ordinary javascript objects will resolve as
properties of that particular object if not masked by formal
parameter, local variable or inner function declarations. And where
the ordinary javascript object have a - watch - property (such as in
JavaScript(tm)) then the Identifier - watch - will resolve as a
reference to the -watch - method of that object.

f "remains undefined" because the FunctionExpression with optional
Identifier does not result in the creation of a named property of the
Activation/Variable object for the execution context in which it is
evaluated (it is not a FunctionDeclaration, which would). That is
until you try this in IE and see the bug that makes using the optional
Identifiers with FunctionExpressions such a bad idea that you would be
best off never attempting it.
From: Jorge on
On May 7, 12:46 pm, Henry <rcornf...(a)raindrop.co.uk> wrote:

> JavaScript(tm) objects have - watch - and - unwatch - methods (as an
> aid to debugging). When a Function Expression is provided with the
> optional Identifier (your 'f' in this case) the specified behaviour is
> to create the corresponding function object with an additional object
> at the top of the scope chain that is referred to by the function's
> internal [[Scope]] property and give that object a name which
> corresponds with the Identifier and a value that refers to the
> function object. A side effect of this is that when the function is
> executed it has an ordinary javascript object on its scope chain and
> so all Identifiers used within the function that correspond with the
> named properties of ordinary javascript objects will resolve as
> properties of that particular object if not masked by formal
> parameter, local variable or inner function declarations. And where
> the ordinary javascript object have a - watch - property (such as in
> JavaScript(tm)) then the Identifier - watch - will resolve as a
> reference to the -watch - method of that object.

Ahh.., so there was beforehand a .watch() method... !
But not in Safari... etc right ?
Only in FireFox ?
And, is that method a part of the standard ?
Why do you write ***JavaScript(tm)*** ?

> f "remains undefined" because the FunctionExpression with optional
> Identifier does not result in the creation of a named property of the
> Activation/Variable object for the execution context in which it is
> evaluated (it is not a FunctionDeclaration, which would). That is
> until you try this in IE and see the bug that makes using the optional
> Identifiers with FunctionExpressions such a bad idea that you would be
> best off never attempting it.

Hmm, I was expecting (function funcName () {})(); to yield a defined
funcName in that context.
Why is that a bad idea ?
You could always have used an unnamed function instead, I mean, if you
didn't intend to get funcName defined... ?

(function () {
var watch = aVar = "Hola !";
(function f () {
alert(aVar);
alert(watch);
alert(typeof f);
})();
alert(typeof f);
})();

IE8b : "Hola !", "Hola !", "function", "function" <- You're right,
IE did it !
Safari : "Hola !", "Hola !", "function", "undefined"
FireFox : "Hola !", "native function ()", "function", "undefined"

Thanks for sharing,
--Jorge.
From: Henry on
On May 7, 12:28 pm, Jorge wrote:
> On May 7, 12:46 pm, Henry wrote:
>> JavaScript(tm) objects have - watch - and - unwatch - methods ...
<snip>
> Ahh.., so there was beforehand a .watch() method... !

Yes.

> But not in Safari... etc right ?

Not yet, but Safari could add one at any moment. Opera's ECMAScript
implementation has - watch - and unwatch - methods on its object for
compatibility with JavaScript(tm), and Safari does do some things for
similar compatibility.

> Only in FireFox ?

Not only (and that is assuming that "FireFox" is taken to mean all
Mozilla/Gecko based web browsers (and there are 20 odd of them by
now).

> And, is that method a part of the standard ?

No. But the standard allows implementations to provide extensions and
those methods are an extension.

> Why do you write ***JavaScript(tm)*** ?

JavaScript, with an uppercase J and an upper case S, is the trademark
name of what is now a single ECMAScript implementation (the one that
originated at Netscape, is now the responsibility of the Mozilla
foundation and appears in Firefox/Mozilla/Gecko browsers). There are
numerous other ECMAScript implementations, such as JScript(tm) in IE
browsers. I tend to use 'javascript' or 'Javascript' (with the non-
trademark capitalisation) to refer to geniality of ECMAScript
implementations (as do many others) and the trademark names to refer
to the specific implementations unambiguously (especially with the
"(tm)" extension) (were they have such names (and I know what those
names are)).

>> f "remains undefined" because the FunctionExpression with
>> optional Identifier does not result in the creation of a
>> named property of the Activation/Variable object for the
>> execution context in which it is evaluated (it is not a
>> FunctionDeclaration, which would). That is until you try
>> this in IE and see the bug that makes using the optional
>> Identifiers with FunctionExpressions such a bad idea that
>> you would be best off never attempting it.
>
> Hmm, I was expecting (function funcName () {})(); to yield a defined
> funcName in that context.

But the specification says that should not happen. FunctionExpressions
and FunctionDeclarations are not handled the same way regardless of
how similar they may appear in some cases.

> Why is that a bad idea ?

Which? Thinking it should create a named property of the variable
object or using the optional Identifiers with FunctionExpressions? The
former is a bad idea because it is at odds with the specification and
the reality of most implementations of that specification. The latter
is a bad idea because IE does not conform to the specification in this
area and what it does do is sufficiently strange as to be
problematic.

> You could always have used an unnamed function instead,
> I mean, if you didn't intend to get funcName defined... ?

The use of the optional Identifier with FunctionExpressions is to
allow code inside the function body to refer to the function object by
name (rather than using - arguments.callee -).

> (function () {
> var watch = aVar = "Hola !";
> (function f () {
> alert(aVar);
> alert(watch);
> alert(typeof f);
> })();
> alert(typeof f);
^^^^^^^^^^^^^^
Try moving this line to above the evaluation of the function
expression to see how badly IE is behaving here.

>
> })();
>
> IE8b : "Hola !", "Hola !", "function", "function" <- You're right,
> IE did it !
<snip>
Yes, and if you it you would discover that the function object that
results form the evaluation of the function expression is not the same
function object as can be referred to using the Identifier in the
containing context.
From: Jorge on
On May 7, 2:27 pm, Henry <rcornf...(a)raindrop.co.uk> wrote:
> On May 7, 12:28 pm, Jorge wrote:
>
> > On May 7, 12:46 pm, Henry wrote:
> >> JavaScript(tm) objects have - watch - and - unwatch - methods ...
> <snip>
> > Ahh.., so there was beforehand a .watch() method... !
>
> Yes.
>
> > But not in Safari... etc right ?
>
> Not yet, but Safari could add one at any moment. Opera's ECMAScript
> implementation has - watch - and unwatch - methods on its object for
> compatibility with JavaScript(tm), and Safari does do some things for
> similar compatibility.
>
> > Only in FireFox ?
>
> Not only (and that is assuming that "FireFox" is taken to mean all
> Mozilla/Gecko based web browsers (and there are 20 odd of them by
> now).
>

I see. But Opera behaves the same as Safari.
FF3 behaves as FF2, but it's JS is not spiderMonkey, isn't it ?
The other spiderMonkeys I've tested all behave as FF2.

--Jorge.
 | 
Pages: 1
Prev: Singleton
Next: Pop-up menu in Dreamweaver