In JavaScript I want to do the following:
var pi = {};
pi[0]['*']['*'] = 1;
of course this throws a "Cannot read property '*' of undefined" error. Clearly I can define p[0] = {}, but that's kind of a pain as I will be sticking lots of different values in the different attributes, e.g.
pi[2]['O']['I-GENE'] = 1;
etc. The first key into the hash is just an integer, so I guess I could use an array at the top level instead of a hash, and then default initialize like in this post:
default array values
but that doesn't handle my need for default initialization of the other hashes.
It does seem like what I am trying to do is running up against the ECMAScript spec which indicates that undefined attributes of an object (which is a hash in JavaScript) should return undefined, as mentioned here:
Set default value of javascript object attributes
which interestingly includes a dangerous work around.
In other places where I'm trying use nested hashes like this I am finding myself writing long bits of ugly code like this:
function incrementThreeGramCount(three_grams,category_minus_two,category_minus_one,category){
if(three_grams[category_minus_two] === undefined){
three_grams[category_minus_two] = {};
}
if(three_grams[category_minus_two][category_minus_one] === undefined){
three_grams[category_minus_two][category_minus_one] = {};
}
if(three_grams[category_minus_two][category_minus_one][category] === undefined){
three_grams[category_minus_two][category_minus_one][category] = 0;
}
three_grams[category_minus_two][category_minus_one][category]++;
}
which I'd really like to avoid here, or at least find some good way of adding to the functionality of the Hash through the prototype method. However it seems like since the Hash and Object in JavaScript are just the same thing, we can't really play around with default hash behaviour in JavaScript without impacting a lot of other things ...
Maybe I should be writing my own Hash class ... or using Prototypes:
http://prototypejs.org/doc/latest/language/Hash/
or someone elses:
http://www.daveperrett.com/articles/2007/07/25/javascript-hash-class/
or mootools:
http://mootools.net/docs/more/Types/Hash
argh, so many choices - wish I knew the best practice here ...
This can be done using ES6 proxies. You'd define a proxy on an object with a get handler. When a get is performed on a key with an undefined value or for which the object doesn't have an own property, you set it to a new proxy that uses the same get handler and return that new proxy.
Additionally, this would work without the need for the bracket syntax:
var obj = ...;
obj.a.b.c = 3;
Unfortunately, being an ES6 feature, their support is limited to Firefox and they can be enabled in Chrome with an experimental flag.
I would do something like that:
Object.prototype.get = function(v){
if(!this[v]){
this[v] = {}
}
return this[v];
}
and then, instead object["x"]["y"].z = 666 use object.get("x").get("y").z = 666.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With