Should I use an empty property key?

Javascript

Javascript Problem Overview


I've tested this only in Firefox, but apparently you can use an empty string as a key to a property in an object. For example, see the first property here:

var countsByStatus = { 
  "": 23, //unknown status
  "started": 45,
  "draft": 3,
  "accepted": 23,
  "hold": 2345,
  "fixed": 2,
  "published": 345
}

In skimming through the EcmaScript specs, it appears that (at least in 5), property keys are defined as strings, and strings as 0 or more characters. This implies that an empty string is a valid property name according to the specs.

Anyway, I'm tempted to use this in a section of code where I'm calculating summaries of some counts by the status of a data item (similar to what I've shown above). There are some items which might not have a status, and I need a placeholder for those. Since statuses are user-definable, I don't want to risk using a dummy word that might conflict.

It seems so simple and elegant, in looking at the data I can easily tell what the blank string would mean. It also makes the code a little bit more efficient, since the empty string would be the exact value of the status in the items without a status.

But at the same time, my instincts are telling me that something is wrong with it. I mean, apart from the chance that some browser might not support this, I feel like I've encountered a bug in JavaScript that will be fixed some day. But, at the same time, that's the same feeling I once had about a lot of other JavaScript features that I now use every day (such as the time I discovered that && and || returns the value of one of the operands, not just true or false).

Javascript Solutions


Solution 1 - Javascript

An object's key must be a string, and the empty string ('') is a string. There is no cross browser issue that I've ever come across with empty strings, although there have been very few occasions where I thought it was acceptable to use an empty string as a key name.

I would discourage the general usage of '' as a key, but for a simple lookup, it'll work just fine, and sounds reasonable. It's a good place to add a comment noting the exceptional circumstance.

Additionally, during lookup you may have issues with values that are cast to a string:

o = {...} //some object
foo = 'bar';

//some examples
o[foo] //will return o['bar']
o[null] //will return o['null']
o[undefined] //will return o['undefined']

If you'd like to have null and undefined use the '' key, you may need to use a fallback:

key = key || '';

If you might have non-string values passed in, it's important to cast too:

key = key || '';
key = '' + key;

note that a value of 0 will turn into '', whereas a value of '0' will stay '0'.


In most cases, I find I'm picking a pre-defined value out of a hashtable object. To check that the value exists on the object there are a number of options:

//will be falsey if the value is falsey
if (o[key]) {...}

//will return true for properties on the object as well as in the prototype hierarchy
if (key in o) {...}

//returns true only for properties on the object instance
if (o.hasOwnProperty(key)) {...}

Solution 2 - Javascript

Technically, there is nothing wrong and you can savely use it on any js engine (that I'm aware of). Since ECMAscripts spec says any object key is a string, it of course can also be an empty string.

The only caveat is, that you'll never be able to access that property with the dot notation

countsByStatus.;

will lead to a syntax error of course, so it always needs to be

countsByStatus[''];

That much about the technical part. If we talk about the convinient part, I'd vote for a very clear no, never use it.

It'll lead to confusion and as we all know, confusion is the enemy.

Solution 3 - Javascript

The problem is that since the statuses are user-defineable there is nothing stoping the user from also using the empty string as a status, thus ruining your logic. From this point of view what you are doing is no different then just using an ugly custom name like __$$unknown_status. (Well, I'd say the ugly custom name is more descriptive but to each its own...)

If you want to be really sure the "unknown" property does not collide you need to keep it separate:

var counts = {
    unknownStatus: 23,
    byStatus: {
        "": 17, //actual status with no name, (if this makes sense)
        "started": 45,
        "draft": 3,
        "accepted": 23,
        "hold": 2345,
        "fixed": 2,
        "published": 345
    }
};

Solution 4 - Javascript

I think it's ok. "" has semantics in your application, and its valid javascript. So have at it.

Note that

x."" = 2;

will error out, so you need to use syntax like

x[""] = 2;

Solution 5 - Javascript

Is "unknown status" a null value or is your status field "not null"?

In the first case I'd say you will have to use a separate counter, in the second I'd say that "empty" is a perfectly valid status - just use the word "unknown" for output instead of "". This might only lead to confusion when your user uses the same word as a status type, but to prevent that you only can use a different visual style for "unknown status" output text.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser4815162342View Question on Stackoverflow
Solution 1 - JavascriptzzzzBovView Answer on Stackoverflow
Solution 2 - JavascriptjAndyView Answer on Stackoverflow
Solution 3 - JavascripthugomgView Answer on Stackoverflow
Solution 4 - JavascripthvgotcodesView Answer on Stackoverflow
Solution 5 - JavascriptBergiView Answer on Stackoverflow