Extending Prototype - cloning hashes
Just as we liked cloning arrays we would love being able to do so with hashes. Ideally, the same method we used to clone arrays could be used to clone hashes. Unfortunately, this is not so.
In JavaScript, hashes – which are usually referred to as associative arrays – do not exist as instances of a special object like arrays do, or like hashes do in most other object oriented languages. They are just instances of Object. There is a pretty good – despite it being rather outdated – explanation on the subject of hashes over at quirksmode.
One could argue that we should just proceed and extend Object as we previously extended the Array object. However, this is usually frowned upon, as not only will it will extend our hash objects with our clone() method, but also every other instances of Object which we (or other libraries we might be using) would create.
To overcome this issue, Prototype has created a special Hash class, which you can read about here. This is the class we will extend with our clone() method.
So, after this long preamble, here finally is the code:
Object.extend(Hash, {
clone: function(){
return Object.extend({}, this);
}
});
It uses a similar technique to our Array::clone() method: creating a new empty object (again using a shorthand syntax {}), before populating it with its content by using the extend() method of Object.
You can use it like so:
var originalStyle = $H({
fontFamily: 'Helvetica, sans-serif',
fontSize: '1em',
fontStyle: 'normal'
});
var emStyle = originalStyle.clone();
emStyle.fontStyle = 'italic';
alert(originalStyle.fontStyle); // returns 'normal'
alert(emStyle.fontStyle); // returns 'italic'
Notice the $H() function which we apply to our initial object. This actually makes Prototype treat it as a hash rather than a regular object. Check out Prototype's source code to find more about it, or read Justin's article mentioned above.
Update: this code is now downloadable as part of xPrototype, my tiny add-on to Prototype.