Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using a javascript object like a java Map?

Tags:

javascript

I need something of a HashMap in javascript. Can we do this:

var map = {};
map['foo'] = true;
map['zoo'] = true;
...

if (map['foo']) {
    // yes, foo exists.
}
else {
    // no, foo does not exist.
}

how do we properly check for the existence of the property without inserting it if it does not exist? For example, I don't want map.foo to exist after the above check if I didn't explicitly add it,

Thanks

like image 202
user246114 Avatar asked Apr 09 '26 12:04

user246114


1 Answers

In your example, checking for:

if (map['foo']) {
  //..
}

Not only checks if the property is not defined on the object, the condition expression of the if statement will evaluate to false also if the property holds a value that coerces to false on boolean context (aka falsy values), such as 0, NaN, an empty string, null, undefined and of course false, e.g.:

var map = {
  'foo': 0 // or any other falsy value
}; 

if (map['foo']) {
  // foo is truthy...
} else {
  // foo is falsy or not defined
}

To check if a property exist on an object, regardless its value -which can be falsy, even undefined- , you can use the hasOwnProperty method, for example:

var map = {};
map['foo'] = 0;

if (map.hasOwnProperty('foo')) {
  // foo exist physically on the object...
}

The only problem with this method is that if someone adds a property named hasOwnProperty to an object, it wont work, for example:

var obj = {
    hasOwnProperty: 'bar'
};

If you execute obj.hasOwnProperty('prop'), it will give you a TypeError, because the object contains a string property that shadows the method -invoking the string would cause the error-.

A workaround to this is to call the hasOwnProperty method directly from the Object.prototype object, for example:

if (Object.prototype.hasOwnProperty.call(obj, 'prop')) {
  //..
}

You can also use the in operator:

if ('prop' in obj) {
  //...
}

The difference with the first method is that the in operator checks also for inherited properties, for example:

var obj = {};
obj.hasOwnProperty('toString'); // false
'toString' in obj; // true, inherited from Object.prototype.toString

See also:

  • Difference between undefined and not being defined in Javascript

Edit:

Extending my response to the @slebetman comment, about checking if (map.foo !== undefined).

As I was commenting, there are some concerns about accessing the undefined global property and also a semantic difference between checking a property value vs. property existence.

The undefined global property is not defined as read-only ECMAScript 3rd Edition Standard, (is now writable = false on ES5 :)

In almost all implementations its value can be replaced.

If someone makes:

window.undefined = 'foo';

// It will break your code:
var obj = {};
if (obj.foo !== undefined) {
  alert("This shouldn't ever happen!");
}

Also the semantic difference: by testing if map.foo !== undefined we are not technically only checking if the property exist on the object or not, a property can exist, holding undefined as a value, for example:

var map = {
  'foo': undefined
};

map.hasOwnProperty('foo'); // true, because the property exists although
                           //       it holds the undefined value
map.foo !== undefined;     // false
like image 180
Christian C. Salvadó Avatar answered Apr 12 '26 02:04

Christian C. Salvadó