Re: undefined vs. undefined (was: new Array() vs [])
- From: "VK" <schools_ring@xxxxxxxxx>
- Date: 10 Sep 2006 05:03:28 -0700
VK wrote:
So indeed it is confirmed to be
a Gecko JavaScript engine bug: see
<https://bugzilla.mozilla.org/show_bug.cgi?id=260106>
So I was wrong and Microsoft was right in this case.
*IMHO*
After thinking it over again tonight, I see no bug in Mozilla. But I
see a specification bug in the referenced ECMAScript section 11.1.4
which is in turn a reflection of erroneus decision once made to allow
undefined value to be *assigned*.
Quote 1
4.3.9 Undefined Value
The undefined value is a primitive value used
when a variable has not been assigned a value.
Quote 2
8.1 The Undefined Type
The Undefined type has exactly one value, called undefined.
Any variable that has not been assigned a value has
the value undefined.
Quote 3
11.1.4 Array Initialiser, preface
.... Elided array elements are not defined.
Quote 4
11.1.4 Array Initialiser, production
(VK: for say [,1,2] array initializer)
....
1. Create a new array as if by the expression new Array().
2. Evaluate Elision; if not present, use the numeric value zero.
3. Call the [[Put]] method of Result(1) with arguments
"length" and Result(2).
4. Return Result(1).
....
Quote 5
8.6.2.2 [[Put]] (P, V)
(VK: referenced on step 3 in the previous quote)
When the [[Put]] method of O is called with property P and value V,
the following steps are taken:
1. Call the [[CanPut]] method of O with name P.
2. If Result(1) is false, return.
3. If O doesn't have a property with name P, go to step 6.
4. Set the value of the property to V. The attributes of the property
are not changed.
5. Return.
6. Create a property with name P, set its value to V and give it empty
attributes.
7. Return.
This way I see a specification bug in 11.1.4 where the preface is in
contradiction with the production. By going by the production, it is
not possible to have "not defined" members in place of elision. There
is an explicit assignment (set) operation involved, therefore we only
can have *members explicetly initialized with undefined value*.
In this respect if we want
arr = [,1,2];
to produce an array that can be treated it as an object with two
properties ("1" and "2", but not "0"): then we also have to request
that
obj = {};
obj.foo = undefined;
would result in an object with no enumerable properties (no <foo>
property).
Technically by the production schema these are totally the same, but no
one seems filing a bug for the later.
That's again: there is a cardinal difference between i) something that
exists and it has explicetly assigned undefined value and ii) something
that doesn't exists anymore or never existed.
Section 11.1.4 requires two opposite things in preface section and in
production section, so it's the programmer's choice what to follow.
Here some code I've made while making my mind together :-) :
<html>
<head>
<title>Untitled Document</title>
<meta http-equiv="Content-Type" content="text/html;
charset=iso-8859-1">
<script type="text/javascript">
var br = '\n';
var p = br + br;
function test1(out) {
out.value = 'Test 1' + p;
// variable <foo> is explicetly initialized
// with undefined value:
var foo = undefined;
// variable <bar> simply doesn't exist
// neither in local nor in global scopes
out.value+= (typeof foo) + br; // "undefined"
out.value+= (typeof bar) + br; // "undefined"
// but later:
try {
out.value+= (foo == 0) + br; // false
out.value+= (bar == 0) + br; // run-time error
}
catch(e) {
out.value+= 'Run-time error: ' + e.message + br;
}
}
function test2(out) {
out.value = 'Test 2' + p;
var obj = new Object();
// property <foo> is explicetly initialized
// with undefined value:
obj.foo = undefined;
// property <bar> simply doesn't exist
// in <obj> object
out.value+= (typeof obj.foo) + br; // "undefined"
out.value+= (typeof obj.bar) + br; // "undefined"
// but only one enumerable property <foo> exists:
for (var prop in obj) {
out.value+= prop + ' = ' + obj[prop] + br;
}
}
function test3(out) {
out.value = 'Test 3' + p;
// initializing array with elision:
var arr = [,1,2];
out.value+= 'length: ' + arr.length + p; // 3
for (var i=0; i<arr.length; i++) {
out.value+= 'arr['+i+'] = ' + arr[i] + br;
}
out.value+= p;
for (var prop in arr) {
out.value+= 'arr.'+prop+' = ' + arr[prop] + br;
}
out.value+= p;
delete arr[0];
for (var prop in arr) {
out.value+= 'arr.'+prop+' = ' + arr[prop] + br;
}
}
</script>
</head
<bodyonClick="test1(this.form.out)"
<form method="post" action=""
<textarea name="out" cols="64" rows="16"></textarea
<br
<input type="button" name="b1" value="Test 1"
<input type="button" name="b2" value="Test 2"onClick="test2(this.form.out)"
<input type="button" name="b3" value="Test 3"onClick="test3(this.form.out)"
</form
</body
</html>
.
- Follow-Ups:
- Re: undefined vs. undefined (was: new Array() vs [])
- From: Michael Winter
- Re: undefined vs. undefined (was: new Array() vs [])
- From: Richard Cornford
- Re: undefined vs. undefined (was: new Array() vs [])
- References:
- undefined vs. undefined (was: new Array() vs [])
- From: VK
- Re: undefined vs. undefined (was: new Array() vs [])
- From: Richard Cornford
- Re: undefined vs. undefined (was: new Array() vs [])
- From: VK
- Re: undefined vs. undefined (was: new Array() vs [])
- From: Richard Cornford
- Re: undefined vs. undefined (was: new Array() vs [])
- From: VK
- undefined vs. undefined (was: new Array() vs [])
- Prev by Date: Re: FAQ Topic - How do I detect Opera/Netscape/IE?
- Next by Date: Re: JavaScript/CSS/DOM issue
- Previous by thread: Re: undefined vs. undefined (was: new Array() vs [])
- Next by thread: Re: undefined vs. undefined (was: new Array() vs [])
- Index(es):