Throughout this book, we've been treating objects and arrays as if they were separate data types. This is a useful and reasonable simplification, and you can treat them as separate data types for most of your JavaScript programming. To fully understand the behavior of objects and arrays, however, you have to know the truth: objects and arrays are the same thing.
You can verify this with the typeof operator--use it with any array or with any object, and it returns the string "object". Because arrays and objects are the same thing, any object can have numerically indexed array elements, and any array can have named properties:
o.prop = "property1" o[1] = "element1" a[3] = a[2] + a[1]; a.size = 3;
Note, however, that because of the ways arrays and objects are implemented in Navigator 2.0, there are some nonobvious consequences of mixing properties and elements that you must beware of. These, and other features of arrays in Navigator 2.0, are discussed later in this chapter.
Code:
//The following demonstration code was very instructive to me: var a = new Array(); a["zero"]=0; a.one=1; a[0]="zero"; a[1]="one"; document.write("<PRE>"); for (i in a) { document.write("<BR>a["+i+"]="+a[i].toString().split('<').join('<')); } /* produces: a[toSourceCode]=function(hier,lv,forObj){ var out,tabs='',idre=/^[a-z_][a-z0-9_]*$/i; if (!lv) lv=0; if (hier) tabs=Math.pow(10,lv).toString().substr(1).replace(/0/g,"\t"); if (this.constructor==Array){ out=(forObj?'':tabs)+'['+(hier?'\n':''); for (var i=0,len=this.length;i<len;i++) out+=((this[i]!=null)?this[i].toSourceCode(hier,lv+1):'null')+(i<(len-1)?',':'')+(hier?'\n':''); return out+tabs+']'; }else if(this.constructor==Object){ out=(forObj?'':tabs)+'{'+(hier?'\n':''); for (var key in this) if (key!='toSourceCode') out+=tabs+(hier?'\t':'')+(idre.test(key)?key:("'"+key+"'"))+":"+(this[key]==null?'null':this[key].toSourceCode(hier,lv+1,true))+","+(hier?'\n':''); out=out.replace(/,(\n?)$/,'$1'); return out+tabs+'}'; }else if(this.constructor==String) return (forObj?'':tabs)+"'"+this+"'"; else if(this.constructor==Date) return (forObj?'':tabs)+"new Date("+this.valueOf()+")"; //else if(this.constructor==RegExp) return (forObj?'':tabs)+this.toString().replace(/([^\\])((?:\\\\)*)\/(?=.*\/)/g,'$1$2\\/'); else return (forObj?'':tabs)+this.toString(); } a[zero]=0 a[one]=1 a[0]=zero a[1]=one */ document.write("<P>a.length="+a.length) //Produces: a.length=2 for (i = 0; i < a.length; i++) { document.write("<BR>a["+i+"]="+a[i]); } /* Produces: a[0]=zero a[1]=one */ document.write("<P>"+a.join(",")+"</PRE>") // Produces: zero,one