'Hoisting' or Parsetime versus Runtime

D

DaveC

Consider the following:

alert(typeof foo);
alert(typeof bar);
alert(typeof baz);

if (0) {
function foo() {
var a = 1;
}

var foo = 10;

var bar = function baz() {
var a = 1;
};
}

alert(typeof foo);
alert(typeof bar);
alert(typeof baz);

Which alerts:

Chrome: function, undefined, undefined, function, undefined, undefined
IE: function, undefined, function, function, undefined, function
Firefox: undefined, undefined, undefined, undefined, undefined,
undefined
Opera: function, undefined, undefined, function, undefined, undefined

Is the effect I'm seeing 'hoisting' (function declarations get
'hoisted' into their containing scope - except in Firefox)? And is
'hoisting' the correct term?

Thanks for any help.
Dave
 
R

Richard Cornford

Consider the following:

alert(typeof foo);
alert(typeof bar);
alert(typeof baz);

if (0) {
function foo() {
var a = 1;
}
^^^^^^^^^^^^^^^^^
In ECMAScript terms this is a syntax error. A function declaration may
not appear inside a statement (the Block statement in this case).

var bar = function baz() {
var a = 1;
};

Is the effect I'm seeing 'hoisting' (function declarations
get 'hoisted' into their containing scope

ECMAScript allows for syntax 'extensions'. A common extension is to
recognise function declarations in contexts where they would not
otherwise be allowed and just treat them as normal function
declarations, where they get 'hoisted'. However, this is copied from
Microsoft's JScript, but in JScript this 'inclusive' handling of
function declarations extends to named function expressions, which get
treated as both 'out of context' function declarations and (later) as
function expressions. Two function objects get created, the first is
if by a function declaration (and gets 'hoisted') and the second is if
by a function expression.
- except in Firefox)?

Mozilla browsers (so JavaScript(tm)) has an alternative syntax
extension which is a 'function statement', which looks like a function
declaration in a statement context, and is treated as a statement.

Generally, and because of the inconsistent handling, it is better to
stick with pure ECMAScript syntax for function declarations.
And is 'hoisting' the correct term?

It is good enough. The 'hoisting' effect is the result of the two
stage processing in code execution where a 'variable instantiation'
stage (in which formal parameters, variables and function declarations
are acted upon) followed by actual code execution (in which things
like assignments to variables occurs).

Richard.
 
D

DaveC

          ^^^^^^^^^^^^^^^^^
In ECMAScript terms this is a syntax error. A function declaration may
not appear inside a statement (the Block statement in this case).




ECMAScript allows for syntax 'extensions'. A common extension is to
recognise function declarations in contexts where they would not
otherwise be allowed and just treat them as normal function
declarations, where they get 'hoisted'. However, this is copied from
Microsoft's JScript, but in JScript this 'inclusive' handling of
function declarations extends to named function expressions, which get
treated as both 'out of context' function declarations and (later) as
function expressions. Two function objects get created, the first is
if by a function declaration (and gets 'hoisted') and the second is if
by a function expression.


Mozilla browsers (so JavaScript(tm)) has an alternative syntax
extension which is a 'function statement', which looks like a function
declaration in a statement context, and is treated as a statement.

Generally, and because of the inconsistent handling, it is better to
stick with pure ECMAScript syntax for function declarations.


It is good enough. The 'hoisting' effect is the result of the two
stage processing in code execution where a 'variable instantiation'
stage (in which formal parameters, variables and function declarations
are acted upon) followed by actual code execution (in which things
like assignments to variables occurs).

Richard.

Thanks Richard,

Your explanation makes sense - just to clarify, the code should be
written as:

function foo() {
var a = 1;
}

if (0) {
var foo = 10;
var bar = function baz() {
var a = 1;
};
}

.... and none of the browsers 'correctly' implement the ECMA Standard -
meaning they should be throwing an Error when the encounter a function
declaration inside a statement (but instead they best guess what the
programmer meant)?

And where JSLint says "Function statements cannot be placed in
blocks..." really means "Function statements probably shouldn't be
placed in blocks..."?

The two stage process is, I think, what I was alluding to in my post
title "Parsetime versus Runtime" - which I read somewhere once... but
doesn't appear to be a correct way of describing what’s going on.

I've read your article (I think) on Jibbering.com a few times (it's
slowly sinking in!) and I've also tried to read and understand the
ECMA Spec doc... and gave up.

Cheers,
Dave
 
R

Richard Cornford

Thanks Richard,

Your explanation makes sense - just to clarify, the code should be
written as:

function foo() {
var a = 1;

}

if (0) {
var foo = 10;
var bar = function baz() {
var a = 1;
};

}

The named function expression is still a problem. You will still find
a 'hoisted' - baz - on IE, even when the function expression cannot be
evaluated.
... and none of the browsers 'correctly' implement the ECMA
Standard - meaning they should be throwing an Error when the
encounter a function declaration inside a statement

No, the ECMA standard allows for syntax extension so there are no
grounds for labelling what happens here as 'incorrect' (except for
JScript's failure to add an object to the scope chain of the named
function expression, as that is a failure to satisfy the spec, not an
extension of the spec).
(but instead they best guess what the
programmer meant)?

And where JSLint says "Function statements cannot be placed in
blocks..." really means "Function statements probably shouldn't be
placed in blocks..."?

That depends on the intention of JSLint. Probably it should not use
the term 'function statement' to refer to a function declaration (as
statements and function declarations are two distinct items in the
languages syntax but both at the same level, and function statements
do exist as a syntax extension (in JavaScript(tm)). If there is an
intent to impose ECMAScript syntax rules then it is perfectly fine to
say "cannot be placed in blocks", as that is not ECMAScript syntax.
The two stage process is, I think, what I was alluding to in my
post title "Parsetime versus Runtime" - which I read somewhere
once...

"Parsetime" would not be appropriate as 'variable instantiation'
occurs each time execution enters a function, so may happen numerous
times for the same function code, while (- eval/new Function - aside)
the parsing of the code would only happen once.
but doesn't appear to be a correct way of describing what’s going
on.

I've read your article (I think) on Jibbering.com a few times
(it's slowly sinking in!) and I've also tried to read and
understand the ECMA Spec doc... and gave up.

Don't give up, it may take some understanding but in the end it is the
document where you find the detail if what behaviour you can expect
from the language, without its being filtered through the
misconceptions and vague terminology of others.

Richard.
 
D

DaveC

The named function expression is still a problem. You will still find
a 'hoisted' - baz - on IE, even when the function expression cannot be
evaluated.


No, the ECMA standard allows for syntax extension so there are no
grounds for labelling what happens here as 'incorrect' (except for
JScript's failure to add an object to the scope chain of the named
function expression, as that is a failure to satisfy the spec, not an
extension of the spec).



That depends on the intention of JSLint. Probably it should not use
the term 'function statement' to refer to a function declaration (as
statements and function declarations are two distinct items in the
languages syntax but both at the same level, and function statements
do exist as a syntax extension (in JavaScript(tm)). If there is an
intent to impose ECMAScript syntax rules then it is perfectly fine to
say "cannot be placed in blocks", as that is not ECMAScript syntax.


"Parsetime" would not be appropriate as 'variable instantiation'
occurs each time execution enters a function, so may happen numerous
times for the same function code, while (- eval/new Function - aside)
the parsing of the code would only happen once.



Don't give up, it may take some understanding but in the end it is the
document where you find the detail if what behaviour you can expect
from the language, without its being filtered through the
misconceptions and vague terminology of others.

Richard.

Thanks again Richard - I'm (slowly) getting there!

OK, so there is what the spec says is ECMAScript and then the
(browser) implementations which can be subtly different because of
extensions to the syntax.

....and the W3C DOM Spec and then the (browser) implementations which
can be subtly different because of extensions... and the CSS spec...
etc, etc.

Is there such a thing as a strict ECMAScript syntax checker I can
download/use? (and if so, would it just trip over (valid) DOM stuff?)

I'm going off topic now, but is there any single resource that gives a
side-by-side comparison of ECMAScript implementations and extensions
(and DOM implementation differences) - I don't know of any, which
isn't to say that there isn't one (I've been doing web development for
about 12 years and I'd like to fully understand at least one of the
areas of web development - JS seem the logical choice).

Specifically, I'd like to demonstate to my superiors and colleagues
that writing xbrowser code is not as difficult as it used to be (or
maybe you think it is!). (We use GWT for building web apps, it outputs
html files containing over 1MB of "compressed" javascript/css which I
find hard to swallow...).

Thanks again for your help.

Cheers,
Dave
 
D

DaveC

Thanks again Richard - I'm (slowly) getting there!

OK, so there is what the spec says is ECMAScript and then the
(browser) implementations which can be subtly different because of
extensions to the syntax.

...and the W3C DOM Spec and then the (browser) implementations which
can be subtly different because of extensions... and the CSS spec...
etc, etc.

Is there such a thing as a strict ECMAScript syntax checker I can
download/use? (and if so, would it just trip over (valid) DOM stuff?)

I'm going off topic now, but is there any single resource that gives a
side-by-side comparison of ECMAScript implementations and extensions
(and DOM implementation differences) - I don't know of any, which
isn't to say that there isn't one (I've been doing web development for
about 12 years and I'd like to fully understand at least one of the
areas of web development - JS seem the logical choice).

Specifically, I'd like to demonstate to my superiors and colleagues
that writing xbrowser code is not as difficult as it used to be (or
maybe you think it is!). (We use GWT for building web apps, it outputs
html files containing over 1MB of "compressed" javascript/css which I
find hard to swallow...).

Thanks again for your help.

Cheers,
Dave

....and just so I understand this correctly 'hoisting' is the result of
syntax extensions in the various implementations and not a feature of
ECMAScript itself?

Again, sorry for all the questions Richard - and thanks for you time
answering them... its scary to think that where I work I'm considered
the 'expert', when my knowledge is so full of holes.

Cheers,
Dave
 
D

DaveC

No, 'hoisting' is ECMAScript.

The semantics (e.g. will they be 'hoisted' or not? or does it even work
at all?) of syntax like those 'function declarations/statements' in an
if statement are possibly subject to extensions.

<snip>

Thanks for the reply Jake.

I think I'm getting there...

When 'we' talk about 'hoisting' we mean which Execution Context the
function declaration will be bound to, which can happen globally (in
between script tags), via eval(), via function.call(this)... (in
ECMAScript) some implementations will 'hoist' from inside
statements...

....an I getting there?

Cheers,
Dave
 
R

Richard Cornford

OK, so there is what the spec says is ECMAScript and then the
(browser) implementations which can be subtly different
because of extensions to the syntax.
Yes.

...and the W3C DOM Spec and then the (browser) implementations
which can be subtly different because of extensions... and
the CSS spec... etc, etc.

In that case they are not extensions. Browsers may provide features in
addition to the DOM specs, not fully implement the modules in the DOM
specs, or not provide all of the modules, but DOM specs do not allow
for 'extensions' as such.
Is there such a thing as a strict ECMAScript syntax checker
I can download/use?

Probably, or at least I have seen claims of as much, but never been
that interested in looking at them.
(and if so, would it just trip over (valid) DOM stuff?)

No it would not. The DOM is an object model with objects that have
properties and methods. You use (syntactically correct) javascript to
interact with that object model, or you don't successfully interact
with it.
I'm going off topic now, but is there any single resource that
gives a side-by-side comparison of ECMAScript implementations
and extensions (and DOM implementation differences) - I don't
know of any, which isn't to say that there isn't one

I have not seen a comprehensive (or fault-free) single source.
(I've been doing web development for about 12 years and I'd
like to fully understand at least one of the
areas of web development - JS seem the logical choice).

It is a reasonable choice if you want to choose a single subject (and
you mean the language, rather than its applications, such as scripting
the DOM). The ES3 spec is fewer than 200 pages (and the ES5 spec not
that much bigger) so it is realistic to become fully familiar with its
contents.
Specifically, I'd like to demonstate to my superiors and
colleagues that writing xbrowser code is not as difficult
as it used to be (or maybe you think it is!).

I don't think it is anything like as difficult as it used to be. When
I started Netscape 4 was still in common use, requiring two very
distinct approaches to browser scripting. These days it is mostly just
scripting the standard DOM.
(We use GWT for building web apps, it outputs html files
containing over 1MB of "compressed" javascript/css which I
find hard to swallow...).
<snip>

That does sound bad.

Richard.
 
R

Richard Cornford

...and just so I understand this correctly 'hoisting' is the
result of syntax extensions in the various implementations and
not a feature of ECMAScript itself?

No, it is a term applied to a feature of ECMAScript to make it more
understandable to people who are used to block-scoped languages. That
feature is 'variable instantiation' (ECMA 262 3rd Ed. Section 10.1.3),
in which all local variables declarations and inner function
declarations are handled as execution enters an 'execution
context' (usually a function call). The result of this is that all
variable declarations appearing at any point in a function's body act
as if they were declared at the top of that function's body in a block-
scoped language; they are "hoisted" to the top of the function body.

The handling of (syntax that looks like) function declarations in
contexts where function declarations are not allowed by ECMAScript is
an extension, but their being treated as function declarations means
that they will be processed during 'variable instantiation'.
Again, sorry for all the questions Richard - and thanks for
you time answering them... its scary to think that where I
work I'm considered the 'expert', when my knowledge is so
full of holes.

I have been in that position ;-)

Richard.
 
D

DaveC

No, it is a term applied to a feature of ECMAScript to make it more
understandable to people who are used to block-scoped languages. That
feature is 'variable instantiation' (ECMA 262 3rd Ed. Section 10.1.3),
in which all local variables declarations and inner function
declarations are handled as execution enters an 'execution
context' (usually a function call). The result of this is that all
variable declarations appearing at any point in a function's body act
as if they were declared at the top of that function's body in a block-
scoped language; they are "hoisted" to the top of the function body.

The handling of (syntax that looks like) function declarations in
contexts where function declarations are not allowed by ECMAScript is
an extension, but their being treated as function declarations means
that they will be processed during 'variable instantiation'.


I have been in that position  ;-)

Richard.

Thanks for the replies Richard.

I remember writing for NS4/IE4... a snippet from my employers
**current** (and revamped) corporate website...

isNS4 = (document.layers) ? true : false;
isIE4 = (document.all && !document.getElementById) ? true : false;
isIE5 = (document.all && document.getElementById) ? true : false;
isNS6 = (!document.all && document.getElementById) ? true : false;

timerID = setTimeout('ha()',20000);

function s(l, p){
if(isIE4 || isIE5){
eval('document.all.menu' + l + '.style.visibility = "visible"');
eval('document.all.menu' + l + '.style.left = p');
}
if(isNS4){
eval('document.layers.menu' + l + '.visibility = "show"');
pos = p;
eval('document.layers.menu' + l + '.left =pos');
eval('document.layers.menu' + l + '.top = 105');
}
if(isNS6){
var myElement = document.getElementById("menu" + l);
myElement.style.left = p;
myElement.style.visibility = "visible";
}
}

Which I hasten to add I wasn't involved in :eek:).

Anyways, thanks for your time - I'm sure I'll have more questions.

Cheers,
Dave
 

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

No members online now.

Forum statistics

Threads
473,996
Messages
2,570,238
Members
46,826
Latest member
robinsontor

Latest Threads

Top