basically , there is no difference between accessing an object's property via the "." syntax or through the key.
var obj = new function(){this.x = "value";}
alert(obj.x === obj['x']); //it will output true
There are times when you can't use the "." , because the name of the property you're trying to access is not a valid variable name (as you pointed with your numeric key) :
var obj = new function(){this['my-value'] = "my value";}
alert(obj['my-value']); // it will output "my value"
alert(obj.my-value); // it will trigger an exception , because the javascript
//interpretor interprets "obj.my-value" as the
//property "my" of obj minus the variable "value"
The big difference is the way the browser handles your syntax . As you can see here , a friend of mine did some testing and it seems that Chrome and IE work a lot faster with the dot syntax while Firefox and Safari are more "keen on" the key syntax.
In conclusion, you can use almost every time either one of them , although there are situations where the "." comes a bit "unprepared".
About the prototype syntax, well, when you define an object you can attach members to every instance , but you can also attach members to the prototype of the object, meaning that whenever a new object of your defined type is created, it will automatically inherit that member from it's prototype. I think it's better understood with an example:
function Point(x,y){this.x = x;this.y = y;}
Point.prototype.toString = function(){
return "I am a point with my x coord at "+this.x+" and my y coord at "+this.y;
}
function Point2(x,y){
this.x = x;
this.y = y;
this.toString = function(){
return "I'm a point too.I'm at x:"+this.x+", y:"+this.y;
};
}
When you create a new Point2
, it's toString
method an instance method and the javascript interpretor allocates memory for this method.
When you create a 'new Point', it's toString
method will be chained on it's prototype property. That means that no memory is allocated for that method.
var p = [], p2 = [];
for(var i = 0; i < 100000000; i++)
{
p.push(new Point(0,0));
p2.push(new Point2(0,0));
}
If you test this, you'll see that both of the objects are working perfect, but your Point2
objects will take a bit more memory out of your system. Why is that?
The thing is that when you call a new Point()
's toString()
method, the object realizes that it doesn't have a member called "toString" and it starts to search for it up it's prototype chain and returns the 'toString' member found in the object's declaration.
In the above example, all of the p
's items will point their toString
method to the one mentioned in the prototype, while all of p2
's items will point to their each copy of the method.
In addition, if you later want to modify the toString
method, it will be very easy to modify it for all the Point
instances :
Point.prototype.toString = function(){return "I'm a smarter point";};
After that, every instance of new Point
will return "I'm a smarter point" when you call it's toString
method.
If you try to modify it for the Point2
instances, it's a bit harder. You will find out that Point2.toString = function(){return "I'm a dumber point";}
will not work as expected, you will have to manually change the method for each instance :
for(var i in p2)
p2[i].toString = function(){return "I'm a dumber point";};
I'll let you decide on which method is better :P