math4tots math4tots - 5 months ago 18
Javascript Question

Are bare objects in javascript part of the ECMAScript standard?

I've come across this article that suggests using 'bare objects' for your hashmap needs if your keys are always strings.

Bare objects are objects created using

null
as the prototype value, for instance with
Object.create(null)
. Using the object literal notation (i.e.
{}
) do not create a bare objects since they set
Object.prototype
as the prototype.

The article points out that the great thing about bare objects is that you can use them as hashmaps without having to worry about builtin keys like
toString
potentially causing bugs when using a key with the same name.

Is this behavior part of the ES5 and/or ES6 standard? That is, if I use bare objects as string key hashmaps in my code, can I rely on my code behaving in the way that I would expect? Are there any caveats to here?

Answer

First of all, ECMA-Script 2015 and above has collections like Hash. That is, in newer JavaScript implementations you don't need to simulate dictionaries/hashmaps/hashtables with objects anymore.

The article points out that the great thing about bare objects is that you can use them as hashmaps without having to worry about builtin keys like toString potentially causing bugs when using a key with the same name.

The article ignores that you don't need to worry about toString in literal objects because there're well-supported functions to get own object's properties without walking through the prototype chain.

For example, let's say I've declared a literal object as follows: var obj = { text: "Matias" };.

A regular for..in loop would iterate Object.prototype properties, but Object.keys will iterate own object properties only:

Object.keys(obj).forEach(propertyName => {
    var someOwnProperty = obj[propertyName ];
});

In addition, a regular for..in could work as Object.keys using Object.prototype.hasOwnProperty:

for(var propertyName in obj) {
    if(obj.hasOwnProperty(propertyName)) {
       // True if property is declared on obj and not in some 
       // level of the prototype chain
    }
}

Is this behavior part of the ES5 and/or ES6 standard? That is, if I use bare objects as string key hashmaps in my code, can I rely on my code behaving in the way that I would expect? Are there any caveats to here?

Object.create was introduced in ECMA-Script 5. It behaves as you expect in almost any modern Web browser and NodeJS.