DEV Community

Cover image for Thinking in {} objects
Joel Ruiz
Joel Ruiz

Posted on

Thinking in {} objects

Objects, hashmaps, maps, dictionaries, it goes by many names, but one thing remains the same.

They are your best weapon at optimization and keeping code elegant.

Arrays vs Objects, believe it or not, they both have their time and place in your code. We cannot cheat our computer's limitations, but we can easily hit 70% or more efficiency with just these two, while the other 30% may require different data structures.

If you haven't learned how objects work under the covers, take a look at this image below.

Alt Text

Hashmaps start with the string key converted to a hash number, and then using the modulus operator, the number is bound to the range of 0 to array length. There are extra steps for collisions, but it's negligible in the grand scheme of performance.

Let's get down to business with some simple examples to skyrocket your optimization.


Battle #1: select, if, objects

//-----------------------------------
//select statements
select(state) {
    case 'Texas': return 1;
    case 'California': return 2;
    case 'Florida': return 3;
    case 'Colorado': return 4;
}

//-----------------------------------
//if statements
if( state === 'Texas' ) return 1;
else if( state === 'California' ) return 2;
else if( state === 'Florida' ) return 3;
else if( state === 'Colorado' ) return 4;

//-----------------------------------
//object initialization
let states = {};
states['Texas'] = 1;
states['California'] = 2;
states['Florida'] = 3;
states['Colorado'] = 4;
//...
//object get value
return states[state] || 0;

Do you see which one is the best? It is {} every time. The object can be initialized at the start of your app into memory, and then accessed whenever needed later. This gives you the option to write the object in a configuration JSON file for easy modification. The switch and if statements, on the other hand, have to be processed every time and have to be hard-coded.


Battle #2: search in arrays, objects

//-----------------------------------
//Arrays #1, loop to find
for(let i arr)
    if (arr[i] == 'Texas') return true;

//-----------------------------------
//Arrays #2, use helper function
return arr.includes('Texas');

//-----------------------------------
//Objects #1, use 'in' syntax
return ('Texas' in obj);

//-----------------------------------
//Objects #2, check if undefined
return obj['Texas'] != undefined;

//-----------------------------------
//Objects #3, use helper function
return obj.hasOwnProperty('Texas'):

Arrays will always have to loop and check each index. Even array.includes will loop behind the scenes. If you have 100,000 items in array, your program will lag.

Objects only need to calculate the hash number of a string. Note, you may see a performance boost if using 1 character string vs 32 character string, as it has to loop through each character to create the hash number.


Battle #3: insert into arrays, objects

let insertPos = 5;
let value = 'Texas';

//-----------------------------------
//Arrays #1, move items up 1 and insert
for(let i=arr.length; i>insertPos; i--)
  arr[i] = arr[i-1];
arr[insertPos] = value;

//-----------------------------------
//Arrays #2, use helper function
arr.insert(insertPos, value);

//-----------------------------------
//Objects #1, set directly at mapped position
obj[insertPos] = value;

Again, don't be fooled by the array.insert function. It has to move the other indices further up the array by 1 behind the scenes just like the for loop.

Objects never have to push elements, as their home is unique. I must say though if your object's hidden array fills up, it will have to copy the values to a bigger hidden array.


Battle #4: static functions, dynamic functions

let command = 'min'
let x = 5;
let y = 3;

//-----------------------------------
//Static
function min(a, b) return a < b ? a : b;
function max(a, b) return a > b ? a : b;

if (command === 'min')
    min(x,y);
else if (command === 'max')
    max(x,y);

//-----------------------------------
//Dynamic
let mathlib = {};
mathlib.min = function(a, b) return a < b ? a : b;
mathlib.max = function(a, b) return a > b ? a : b;

mathlib[command](x,y);

This short example shows using a custom command, perhaps selected by a user.

Arrays may appear as the clear winner, and it might be with very few commands.

However, your code will quickly grow into a big mess of if statements. If you consider growth, and knowing that objects will always scale more elegantly, your codebase will remain readable and maintainable.


If you need to sort the data in an Object, you will be forced to copy it into an array, and this is perfectly fine.

Now, go take advantage of mapping, and control your performance.

Top comments (0)