3

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 JavaScript 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", the user gets back a function, not an int! Is there a way to make sure any string the user gives me is only something I define?

Is the only solution something like the following?

delete aa['toString'];
delete aa['hasOwnProperty'];

etc...

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Claudiu
  • 224,032
  • 165
  • 485
  • 680

3 Answers3

4

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.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Moss Collum
  • 3,542
  • 3
  • 25
  • 23
4

This may work for you:

function getValue(id){
  return (!isNaN(aa[id])) ? aa[id] : undefined;
}

Alternatively, I recommend this generic solution:

function getValue(hash,key) {
    return Object.prototype.hasOwnProperty.call(hash,key) ? hash[key] : undefined;
}

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". It 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, let’s 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".
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
some
  • 48,070
  • 14
  • 77
  • 93
  • yup, the 2nd would work - thanks! the first will not at all, i don't think =P. – Claudiu Dec 15 '08 at 05:20
  • It has to be Object.prototype.hasOwnProperty.call(hash, key) The call method of any function object allows us to call the hasOwnProperty method as if it were a method of the hash object – pottedmeat Dec 15 '08 at 05:35
  • @Claudio: The first one (with isNaN) works because a function or undefined is not a number. So by testing if aa[id] is a number, you get that number, or else you get undefined. I have tested it in firefox and it works there. – some Dec 15 '08 at 06:37
  • @Claudio: And you said you wanted a number, right? ;) But the second one is more generic and works for all types of values. Just remember that internally the key is a string. – some Dec 15 '08 at 06:43
  • @some: ah, thanks, i didn't catch that. my use case was actually more general. the key is a string? isn't it a hashed version of whatever you pass in? or is it the hashed version of the string. if it is, then how does it work for objs you define yourself? – Claudiu Dec 15 '08 at 07:31
  • @Claudio: No, its not hashed. The "key" is the name of the attribute in the object, and therefore must be a string (internally .toString() of the key will be called so you can use a numeric, but it will silently be converted to a string ) – some Dec 15 '08 at 08:31
  • @some: very interesting about the hash, very valuable information! thanks. wish i could double-upvote you. – Claudiu Dec 15 '08 at 12:23
  • @Claudiu: Too bad I put this as community wiki then ;) (and sorry for misspelling your name) – some Dec 15 '08 at 13:30
2

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];
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
annakata
  • 74,572
  • 17
  • 113
  • 180