views:

1944

answers:

7

I don't know how to extend the map object with prototype and hope you can help. I have something like this:

var map = {'one':1, 'two':2};

and I would like to have a method to check for the existence of a key:

if (map.containsKey('one')){...}

How would I extend the map object?

A: 

The simplest way to do this is to add a function directly in the object:

map.containsKey = function(key) {
    return this[key] ? true : false;
};
Maurice Perry
nice, it works for now. How do I generalize it to work if I have several instances of maps?
Haoest
@Haoest: Since you are using regular Javascript object as a map, Object already has the function hasOwnProperty.
Chetan Sastry
ic, many ways to skin this cat </cat_hating>
Haoest
this doesn't check for a property's existance, but it's value in boolean contexts; also, it's somewhat ugly: use `return Boolean(this[key])` or `return !!this[key]` to cast to boolean
Christoph
+1  A: 

These are not "maps" they are objects. Building on Maurice's answer, if you want this to apply to all objects:

Object.prototype.containsKey = function(key) {
    return this.hasOwnProperty(key);
};
Sean Bright
Or you could just use hasOwnProperty so that map.containsKey('containsKey') doesn't always return true!! :p
Chetan Sastry
I've updated my answer. Thanks.
Sean Bright
Noooo! Leave Object.prototype alone.
Crescent Fresh
I think what Chetan wanted to tell you is that there's not much sense in renaming `hasOwnProperty()` to `containsKey()`, and that your solution might break code which uses `in` where it should use `hasOwnProperty()`
Christoph
A: 

In Javascript, you do not need such method really.

if ( map['one'] ) {
   // do something
}

should do it

Amit
Except when 'one' is defined and is falsy. Or if 'one' is derived from the object's prototype and not really it's own property.
Chetan Sastry
+8  A: 

It's dangerous to modify Object.prototype, because it affects all objects and will usually break other libraries you may be using. In general, if you want to add methods to a dictionary-like object, you should create an object for your hash instances to inherit from, like the Prototype Hash object.

For this specific instance, you should really just use either if (key in map) or if (map.hasOwnProperty(key)).

Miles
+4  A: 

There is already an operator to test the existence of a key inside an object.

(In JavaScript, objects are implemented as maps so actually there is no real map.)

if( 'one' in map ) 
{
   alert(map['one']);
}
Vincent Robert
A: 

As other's have said, extending Object.prototype might not be a good idea if your code has to play nice with code written by people ignorant of hasOwnProperty().

Anyway, there are three 'correct' ways I know of to check if a property is available:

obj.hasOwnProperty(name)

checks if a property with given name exists in the object.

name in obj

additionally includes properties inherited via an object's prototype chain.

typeof obj[name] !== 'undefined'

will additionally evaluate to false if the property is present but has been set to undefined.

Some non-JS object's (e.g. window.external in IE) might not implement hasOwnProperty(), so one of the other checks has to be used.

Christoph
A: 

ummm lol

return !! this[key]

never use ? true : false

TJ Holowaychuk