Associative array without toString, etc
-
21-08-2019 - |
Question
I want to create an associative array:
var aa = {} //equivalent to Object(), new Object(), etc...
and I want to be sure that any key I access is going to be a number:
aa['hey'] = 4.3;
aa['btar'] = 43.1;
I know JS doesn't have typing, so I can't automatically check this, but I can ensure in my own code that I only assign strings to this aa.
Now I'm taking keys from the user. I want to display the value for that key. However, if the user gives me something like "toString", he'll get back a function, not an int! Is there any way to make sure any string he gives me is only something I define? Is the only solution something like:
delete aa['toString'];
delete aa['hasOwnProperty'];
etc...
Solution
Will this work for you?
function getValue(id){
return (!isNaN(aa[id])) ? aa[id] : undefined;
}
Update:
With the help from Moss Collum and pottedmeat I recommend this generic solution:
function getValue(hash,key) {
return Object.prototype.hasOwnProperty.call(hash,key) ? hash[key] : undefined;
}
Update2: Had forgot the ".call". (thanks pottedmeat for pointing that out)
Update3: (About the key)
Note the following: The key will internally be converted to a string because the key is actually a name of an attribute.
var test = {
2:"Defined as numeric",
"2":"Defined as string"
}
alert(test[2]); //Alerts "Defined as string"
If trying to use an object:
var test={}, test2={};
test[test2]="message"; //Using an object as a key.
alert(test[test2]); //Alerts "message". Looks like it works...
alert(test[ test2.toString() ]);
//If it really was an object this would not have worked,
// but it also alerts "message".
Now that you know that it is always a string, lets use it:
var test={};
var test2={
toString:function(){return "some_unique_value";}
//Note that the attribute name (toString) don't need quotes.
}
test[test2]="message";
alert(test[ "some_unique_value"] ); //Alerts "message".
OTHER TIPS
One possibility would be to use hasOwnProperty to check that the key is something you explicitly added to the array. So instead of:
function findNumber(userEnteredKey) {
return aa[userEnteredKey];
}
you'd say:
function findNumber(userEnteredKey) {
if (Object.prototype.hasOwnProperty.call(aa,userEnteredKey))
return aa[userEnteredKey];
}
Alternately, you could use typeof to check that anything is a number before returning it. But I like the hasOwnProperty approach, because it'll keep you from returning anything that you didn't intentionally put in the array.
Really simple answer: when you create a new key prepend it with some string constant of your own.
var a = {};
var k = 'MYAPP.COLLECTIONFOO.KEY.';
function setkey(userstring)
{
a[k+userstring] = 42;
}
function getkey(userstring)
{
return a[k+userstring];
}