Client-side JavaScript weirdness with assigning a form element -in Windows / IE6 only. Any ideas?

D

Doug Lerner

I have this snippet of client side code running:

var makeField = document.forms[0][makeFieldName];

alert("makeFieldName name,length,type=" + makeFieldName + ", " +
makeField.name + "," + makeField.length + "," + makeField.type);


The alert is just in there for debugging.

The function containing this code is called when a select field option is
changed. makeFieldName is the name of the select field in the form.

It works correctly from:

OS X / Safari
OS X / IE
OS X / Firefox
Windows / Firefox

but doesn't work right in Windows / IE6.

The diagnostic alert that shows up from all the browsers except Windows /
IE6 is the same:

makeFieldName name,length,type=1_onlyCarMake, 1_onlyCarMake,63,select-one

In other words, the makeFieldName is correct (1_onlyCarMake), and is the
same as makeField.name. The correct field is found and it has the right
number of options and the correct type for a select field.

But in Windows / IE6 only the diagnostic alert shows up with:

makeFieldName name,length,type=1_onlyCarMake, startWith,undefined,hidden

The startWith field happens to be the first field in that form (the only
form in the document, by the way) and it is, in fact, a hidden field. Thus
it makes sense that the length shown is undefined, since it is not a select
field and thus has no options array.

The problem is - why is Windows /IE6 incorrectly returning that field as a
result of the expression "document.forms[0][makeFieldName]" when all the
other browsers are returning the correct field?

It doesn't make any different whether I use document.forms[0][makeFieldName]
or actually specify the name of the form, as in
document["thisFormName"][makeFieldName]. In either case it works everywhere
but in Windows / IE6.

Anybody have any idea why the client is confused and returning the first
form element rather than the named one?

Thanks!

doug
 
D

Doug Lerner

I fixed it! It's definitely a weird Windows-only IE-only bug.

Another staff member had taken part of my code and transplanted it. When she
did this she created a couple of rather strange-looking identifiers that I
never would have made, like "1_onlyCarMake, starting with an integer.

Those are illegal JavaScript identifiers if they are used in the
dot.notation syntax. But they *should* be perfectly legal if used in the
associative array syntax (in quotes, in square brackets), which we were
doing.

It was fine in all the browsers except Windows / IE6 choked on them.

When I changed the identifiers to something that didn't start with an
integer, like onlyCar1Make, it all worked in all browsers.

Just something to be aware of when coding for Windows / IE!

doug
 
R

Richard Cornford

Digital said:
Be careful relying on this implementation.

It has often been observed that individuals who top-post to Usenet show
evidence of not actually reading the messages that they are responding
to. In this case I suspect that the (minimal) discipline of creating a
well-formed Usenet post, with responses following trimmed quotes of
preceding messages that provide the context for the response, would have
avoided your posting an essentially irrelevant response.
What you are running into in IE6 is not a bug, rather you
may consider it compliance with standards. Browsers are
becoming more and more standards compliant. When the
aforementioned browsers conform to Item 7.6 in the ECMAScript
Language Specification your code will no longer work in
those browsers. <snip>

However:-

Doug Lerner wrote:
<snip>

- so the applicable section of ECMA 262 is section 11.2.1, where the
production rules and algorithms for the bracket notation property
accessor make it clear that ECMAScript places no restrictions upon the
sequences of characters that may be used as the property names of
object, and accessed with bracket notation.

The correspondence of a property name with an Identifier is only
significant for dot notation property accessors.

Richard.
 
L

Lasse Reichstein Nielsen

Richard Cornford said:
- so the applicable section of ECMA 262 is section 11.2.1, where the
production rules and algorithms for the bracket notation property
accessor make it clear that ECMAScript places no restrictions upon the
sequences of characters that may be used as the property names of
object, and accessed with bracket notation.

Very true. While I thought I had understood this, it was still
something of an experience when I realised that the empty string
was a valid property name :)

var x = {};
x[""] = 42;
alert(x[""]);

Well, I think it's cute. :)
/L
 
D

Doug Lerner

I did mention in my note that I changed the identifier.

But isn't what you are saying only true with respect to actual identifiers?

If you are using the associative array syntax it shouldn't matter because
properties are really only associative array elements.

So while

a.1_something

is definitely not legal,

a["1_something"]

is perfectly legal.

What is inside brackets does not have to be a "legal indentifier". In fact,
that is one purpose of having that notation (the other being able to have
dynamically named properties).

That's why I think it is a bug for IE6 not to recognize that.

doug



Be careful relying on this implementation. What you are running into in IE6
is not a bug, rather you may consider it compliance with standards.
Browsers are becoming more and more standards compliant. When the
aforementioned browsers conform to Item 7.6 in the ECMAScript Language
Specification your code will no longer work in those browsers.

An identifier is described as:

IdentifierStart::
UnicodeLetter
$
_
\ UnicodeEscapeSequence

A NumberLiteral does not conform to this standard. The reason for this is
demonstrated more clearly in section 7.8.3 while defining HexIntegerLiteral.
It states:

"The source character immediately following a NumberLiteral must not be an
IdentifierStart or DecimalDigit."

The browsers in which your code works are ignoring the IdentifierStart
definition and holding to wording in 7.8.3 to imply that any characters
directly following a NumberLiteral must be part of an Identifier because an
IdentifierStart may not immediately follow a NumberLiteral. The biggest
drawback to this interpretation is going to be in the debugging arena. The
debugging will not be as accurate or as informative. More than likely this
will be realized by the browser authors and the code in question will no
longer be valid. If you continue to code in this manner may I suggest that
you declare all your variables with the 'var' statement. This will not keep
your code from breaking should the standard be adopted. However it will
make your debugging experience much more efficient and enjoyable.

~Digital~


Doug Lerner said:
I fixed it! It's definitely a weird Windows-only IE-only bug.

Another staff member had taken part of my code and transplanted it. When
she
did this she created a couple of rather strange-looking identifiers that I
never would have made, like "1_onlyCarMake, starting with an integer.

Those are illegal JavaScript identifiers if they are used in the
dot.notation syntax. But they *should* be perfectly legal if used in the
associative array syntax (in quotes, in square brackets), which we were
doing.

It was fine in all the browsers except Windows / IE6 choked on them.

When I changed the identifiers to something that didn't start with an
integer, like onlyCar1Make, it all worked in all browsers.

Just something to be aware of when coding for Windows / IE!

doug


I have this snippet of client side code running:

var makeField = document.forms[0][makeFieldName];

alert("makeFieldName name,length,type=" + makeFieldName + ", " +
makeField.name + "," + makeField.length + "," + makeField.type);


The alert is just in there for debugging.

The function containing this code is called when a select field option is
changed. makeFieldName is the name of the select field in the form.

It works correctly from:

OS X / Safari
OS X / IE
OS X / Firefox
Windows / Firefox

but doesn't work right in Windows / IE6.

The diagnostic alert that shows up from all the browsers except Windows /
IE6 is the same:

makeFieldName name,length,type=1_onlyCarMake, 1_onlyCarMake,63,select-one

In other words, the makeFieldName is correct (1_onlyCarMake), and is the
same as makeField.name. The correct field is found and it has the right
number of options and the correct type for a select field.

But in Windows / IE6 only the diagnostic alert shows up with:

makeFieldName name,length,type=1_onlyCarMake, startWith,undefined,hidden

The startWith field happens to be the first field in that form (the only
form in the document, by the way) and it is, in fact, a hidden field.
Thus
it makes sense that the length shown is undefined, since it is not a
select
field and thus has no options array.

The problem is - why is Windows /IE6 incorrectly returning that field as
a
result of the expression "document.forms[0][makeFieldName]" when all the
other browsers are returning the correct field?

It doesn't make any different whether I use
document.forms[0][makeFieldName]
or actually specify the name of the form, as in
document["thisFormName"][makeFieldName]. In either case it works
everywhere
but in Windows / IE6.

Anybody have any idea why the client is confused and returning the first
form element rather than the named one?

Thanks!

doug
 
R

Richard Cornford

Digital wrote:
Section 11.2.1 makes one explicit statement about Identifiers
and identifier-strings:

"where <indentifier-string> is a string literal containing
the same sequence of characters as the Identifier."

You are reading too much into what is actually an explanatory text. That
section is explaining that when a bracket notation property accessor
uses exactly the same character sequence as the property name as a dot
notation property accessor their behaviour is identical. In order to
express the equivalence in behaviour it is necessary for the bracket
notation property accessor to use a property name that is an Identifier
because that restriction applies to dot notation.

This allows the specification to define actual behaviour of property
accessors with a single algorithm and leave the production rules for dot
notation to imply the additional restriction upon the token following
the dot.

The specified productions for bracket notation property accessors are:-

MemberExpression [ Expression ]
CallExpression [ Expression ]

Section 11.2.1 is the only section in the specificiation that
makes mention of identifier-strings.

And only in an explanation of behaviour.
Therefore Section 11.2.1 should be taken literally to mean
that the indentifier-string in bracket notation should
contain the same sequence of characters as if the
identifier-string were to be used as an Identifier as there
are no other ECMA 262 rules that can take precedence.

The algorithm actually takes precedence:-

<quote cite="ECMA 262, 3rd ed. section 11.2.1">
The production MemberExpression : MemberExpression [ Expression ] is
evaluated as follows:

1. Evaluate MemberExpression.
2. Call GetValue(Result(1)).
3. Evaluate Expression.
4. Call GetValue(Result(3)).
5. Call ToObject(Result(2)).
6. Call ToString(Result(4)).
7. Return a value of type Reference whose base object is Result(5)
and whose property name is Result(6).

The production CallExpression : CallExpression [ Expression ] is
evaluated in exactly the same manner, except that the contained
CallExpression is evaluated in step 1.
</quote>

Where we find no examination of the nature of the string that will stand
as the object's property name. If any restriction were intended it would
have to be applied in that algorithm, and after the evaluation of the
Expression within the brackets.
To mazimize the life of code written one should comply.

No such restriction applies so complying with it is unnecessary. It is
also practically impossible to comply because the 'array index' members
of an array can only be accessed by bracket notation property accessors
(the specification contains no alternative mechanism), and an 'array
index' cannot qualify as an Identifier.
Again, this is most important when it comes to creating and
using debuggers ... <snip>


Richard Cornford" <Richard...
<snip>

Please do not top-post to comp.lang.javascript. Even if you do not care
for the long established Usenet conventions your example has potential
to do harm to others.

Richard.
 

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,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top