Deep Dive into Objects in JavaScript

What are Objects

Objects are core data structures in JavaScript, an object is a super important data structure because it typically is used or helps us reflect real-world entities. Now technically, objects in JavaScript are of course data structures that are made up of properties. These are key-value pairs and methods. Methods, in the end, are also key-value pairs but the value is a function that's tied to that object.

So, we can say that properties are variables in the object and methods are functions in an object. We use properties to store data that somehow is related to the same object and then maybe some actions that make sense for this object.

In the end, objects allow us to group related data and allow us to split our code into logical pieces.

Objects and Primitive Values

Objects are reference values. Objects are of course made up of primitive values

const complexPerson =  {
    name: 'ABC',
    hobbies: ['Sports','Cooking'],
    address: {
        street: 'Some Street 5',
        stateId: 5,
        country: 'Germany',
        phone: {
            number: 123456789,
            isMobile: true
        }
    }
}
  • Even though complexPerson has multiple nested reference values (nested arrays and objects), you end up with primitive values if you drill into this object.

  • name holds a String ('ABC') -> Primitive Value

  • hobbies hold an array (i.e., a reference value) which is full of strings ('Sports', 'Cooking') => Primitive values

  • address holds an object which in turn holds a mixture of primitive values like 'Some Street 5' and nested objects (phone), but if you dive into the phone, you find only numbers and booleans -> Primitive values

So, you could say, Primitive values are the core building blocks that hold your data, objects (and arrays) help organize and work with that data.

Adding, Modifying and Deleting Properties

JavaScript object is a collection of properties and a property is an association between a name or key and a value.

const list = [
    {
        name: 'Michael Scott',
        company: 'Dunder Mufflin',
        designation: 'Regional Manager',
        show: 'The Office'
    },
    {
        name: 'Barney Stinson',
        company: 'Golaith National Bank',
        designation: 'Regional Manager',
        show: 'How I met your mother'
    },
    {
        name: 'Jake Peralta',
        company: 'NYPD',
        designation: 'Detective',
        show: 'Brooklyn 99'
    }
];

Add Property to an Object

One can add the property to an object by simply giving it a value. we are adding the property of the husband and giving the value directly. We can use bracket while assigning the value too.

let brooklynNineNine =  {
    name: 'Raymond Holt',
    currentRole: 'Captain of brooklyn99'
}
brooklynNineNine.husband = 'Kevin'
console.log(brooklynNineNine);

One can use ES7 syntax and functional approach and add the property which would yield the same result.

let list = {
    name: 'Michael Scott',
    company: 'Dunder Mufflin',
    designation: 'Regional Manager',
    show: 'The Office'
}
newObject = { ...list, partner: 'Holly Flax' }
console.log(newObject)

Delete property from an Object

One can delete the property from the object using the keyword delete. The delete keyword deletes both the value of the property and the property itself. After deletion, the property cannot be used before it is added back again.

let brooklynNineNine = {
  name: 'Amy Santiago',
  currentRole: 'Detective brooklyn99',
  husband: 'Jake Peralta',
  mentor: 'Raymond Holt'
}
delete brooklynNineNine.mentor;
console.log(brooklynNineNine)

Update the value of the existing property

One can update the value of the property just by reassigning the value to the same key.

let favChar = {
  name: 'Michael Scott',
  company: 'Dunder Mufflin',
  designation: 'Regional Manager',
  show: 'The Office'
}
favChar.designation = 'Hero of Threat Level Midnight'
console.table(favChar)

Add properties to the array of Object

Consider we have an array of objects and we want to add the property to every object in the array. We can achieve this using many array methods(also using for loop). But here I have used the array method .forEach to iterate through the array and add the property to the object.

const list = [
  {
    name: 'Michael Scott',
    company: 'Dunder Mufflin',
    designation: 'Regional Manager',
    show: 'The Office'
  },
  {
    name: 'Barney Stinson',
    company: 'Golaith National Bank',
    designation: 'Please',
    show: 'How I met your mother'
  },
  {
    name: 'Jake Peralta',
    company: 'NYPD',
    designation: 'Detective',
    show: 'Brooklyn 99'
  },
]
list.forEach(function (element) {
  element.favCharacter = "true";
});
console.table(list)

Delete properties from the array of Object

Here, delete is done similarly to the addition. The iteration is done using the array method .forEach and then the deletion is done using the keyword delete.

const list = [
  {
    name: 'Michael Scott',
    company: 'Dunder Mufflin',
    designation: 'Regional Manager',
    show: 'The Office'
  },
  {
    name: 'Barney Stinson',
    company: 'Golaith National Bank',
    designation: 'Please',
    show: 'How I met your mother'
  },
  {
    name: 'Jake Peralta',
    company: 'NYPD',
    designation: 'Detective',
    show: 'Brooklyn 99'
  },
]
list.forEach(function (element) {
  delete element.designation;
});
console.table(list)

Update every value of the existing property in the array of Objects

Here the array method .every is used to iterate through the elements of the array. The property 'responsibility' is reassigned (‘heart of the show to ‘making people laugh’) to different value.

const list = [
  {
    name: 'Michael Scott',
    company: 'Dunder Mufflin',
    designation: 'Regional Manager',
    show: 'The Office',
    responsibility: 'heart of the show'
  },
  {
    name: 'Barney Stinson',
    company: 'Golaith National Bank',
    designation: 'Please',
    show: 'How I met your mother',
    responsibility: 'heart of the show'

  },
  {
    name: 'Jake Peralta',
    company: 'NYPD',
    designation: 'Detective',
    show: 'Brooklyn 99',
    responsibility: 'heart of the show'

  },
]
list.every(element => element.responsibility = 'making people laugh') // every method is used to iterate through the array
console.table(list)

Deep Dive into Objects

Object Keys in JavaScript

Each key in JavaScript must be a String, Symbol or Number. In the below example, key names 1 and 2 are coerced into Strings

const shoppingCart = {
   1: "apple",
   2: "oranges"
};

It's a difference made clear when you print the object

console.log(shoppingCart);
//Result: {'1':'apple', '2':'oranges'}

There is another rule to keep in mind about key names: if your key name contains spaces, you need to wrap it in quotes. Take a look below object where one of its keys has a space so is wrapped in quotes

const programmer = {
    firstName: 'Phil',
    age: 21,
    backendDeveloper: true,
    language: ["Python","JavaScript","Java"],
    "current project name": "The Amazing app"
};

Object values in JavaScript

A value, on the other hand, can be any data type, including an array, number or boolean. The values in the above example contain these types: string, integer, boolean and array. You can even use a function as a value, in which case it's known as a method.

const animal = {
    type: 'cat',
    name: 'kitty',
    sounds() {
        console.log("meow meow");
};

Now, say you want to add or delete key-value pair. Or you simply want to retrieve an object's value.

How do Dot Notation and Bracket Notation work in JavaScript?

Dot notation and bracket notation are two ways to access and use an object's properties.

Add a key-value pair in JavaScript

To add a key-value pair using dot notation, use the syntax:

const book = {};
book.author = "Jane Smith";
book.publicationYear = 2006;

You can also use dot notation on a key to access the related value.

const basketBallPlayer = {
    name: "James",
    averagePointsPerGame: 20,
    height: "6 feet, 2 inches",
    position: "Shooting Guard"
};
basketBallPlayer.position // Shooting Guard

Delete a Key-value pair in JavaScript

To delete a key-value pair use the delete operator as shown below:

delete basetBallPlayer.height

You will probably find yourself reaching for dot notation frequently, though there are certain requirements to be aware of. When using dot notation, key names can't contain spaces, hyphens or start with a number.

Key-Value pair using Bracket notation in JavaScript

Just like the dot notation, you can use bracket notation to add key-value pair to an object. Bracket notation offers more flexibility than dot notation. That's because key names can include space and hyphens and they can start with numbers.

// Add multi word key name
employee["travels frequently"] = true;
// Add key name that starts with a number and includes a hyphen
employee["1st-territory"] = "Chicago";
// Add a key name that starts with a number
employee["25"] = "total customers";

Employee object will look like this

{
    '25': 'totak customers',
    occupation: 'sales,
    'travels frequently': true,
    '1st-territory': 'Chicago'
}

JavaScript Properties

5 ways to Iterate over JavaScript properties

Object.values

Object.values return a list of object property values. Use this when you only need values and not keys.

let job = {
    name: 'Programmer',
    averageSalary: 60000
};
Object.values(job).forEach(value => {
// Do Something...
});

The result of Object.values(job) is

['Programmer', 60000]

Object.entries

Object.entries returns a list of object property keys and values pairs

[[key1, value1], [key2, value2], [key3, value3]... [keyN, valueN]

As you can see, the keys are returned beside the values. So, use this one in case you want to do something with keys. Let's see how we can manipulate that list:

let book = {
    title: 'Learn JavaScript in 30 Minutes',
    price: 14.3,
    genre: 'Technology'
};
Object.entries(book).forEach(pair => {
    let key = pair[0];
    let value = pair[1];
    // Do something with key and value

Object.entries(book) in the above example will return

[['title':'Learn JavaScript in 30 Minutes'], ['price': 14.3], ['genre': 'Technology']]

Object.getOwnPropertyNames

Object.getOwnPropertyNames returns a list of properties:

[key1, key2,..... key3]
let phone = {
    name: 'Galaxy Note10',
    price: 500.0
};
Object.getOwnPropertyNames(phone).forEach(key => {
    let value = phone[key];
});

The result of Object.getOwnPropertyNames(phone) will be:

['name', 'price']

Object.keys

Object.keys are similar to Object.getOwnPropertyNames, it returns a list of Object keys:

[key1, key2, ..., keyN]

let person = {
    name: 'Amy',
    age: 28
    job: 'Enterpreneur'
};
Object.keys(person).forEach(key => {
    let value = person[key];
});

Object.keys will return

['name','age','job']

Use for-in loop

You can use for...in to iterate over object properties.

let course = {
    name: 'Learn JavaScript through examples',
    level: 'Beginner'
};
for (let key in course) {
    let value = course[key];
}

Note that this loop includes inherited properties. For example, we will create another course object inherited from the object course above

let discountCourse = {
    rate: 25
};
Object.setPrototypeOf(discountCourse, course);
for (let key in discountCourse) {
    console.log(key);
}
// Output:
rate
name
level

It is different from Object.keys because Object.keys only includes the enumerable property keys:

Object.keys(discountCourse); //['rate']

So, in case you want to process separately the inherited properties from the enumerable ones, check if a property is inherited using 'hasOwnProperty'

for (let key in discountCourse) {
    let value = course[key];
    if (course.hasOwnProperty(key)) {
        // Handle Enumerable Property
    } else {
        // Handle inherited property
    }
}

So far we have various ways to loop through an object in JavaScript. It depends on your need to use the one that suits you most. If you need to process only values, pick Object.values. Sometimes you have something to do with the keys too, go for Object.entries then.

For only keys, use Object.keys or Object.getOwnPropertyNames. And for some reason, you have to access inherited properties. In that case, choose for... in loop.

5 Simple ways to rename Object Properties in JavaScript Arrays

Using Map

The map creates a new array and works the same as for each loop for the iterations.

let countries = [
{ id:1, name: "India"},
{ id:2, name: "Canada"},
{ id:3, name: "America"}
];
const transformed = countries.map(({id, name}) => ({
    label: id,
    value: name
}));
console.log("1", JSON.stringify(transformed));
// Output
[{"label": 1, value: "India"},
 {"label": 2, value: "Canada"},
 {"label": 3, value: "America"}]

Using a map with arguments

const transformed2 = countries.map(({
    id: label,
    name: value
}) => ({label, value}));
console.log("2", JSON.stringify(transformed2));
// Output
[{ "label": 1, "value": "India"},
 { "label": 2, "value": "Canada"},
 { "label": 3, "value": "America"}]

Using lodash

const test1 = _.mapKeys({a: 1, b: 2}, function(value, key) {
    return key + value;
});
console.log("3", test1);
// Output
{a1: 1, b2: 2}

If you want to rename Object keys. Let's check out the solution for that

Using lodash for objects for values

var users = {
    'atit': {'user': 'atit', 'age': 40 },
    'mahesh': {'user': 'mahesh', 'age': 15}
};
const test2 = _.mapValues(users, function(o) {return o.age});
console.log("4", test2);
// {atit: 40, mahesh: 15};
// shorthand
const test3 = _.mapValues(users, 'age');
console.log("5", test3);
// {atit: 40, mahesh: 15}

Using Object destructuring

const rename = (({id: a_b_c, ...rest}) => ({a_b_c, ...rest}))
console.log(rename({id: 1, val: 2}))
// {a_b_c: 1, val: 2}

JavaScript Object Properties Ordering

Array Indexes in ascending numeric index order

const object = {
    100: 100,
    '2': 2,
    12: 12,
    '0': 0
};
console.log(Object.keys(object);
console.log(Object.keys(object.getOwnPropertyNames(object));
console.log(Reflect.ownKeys(object);
for (const key in object) {
    console.log('key: ', key);
}
Output:
['0', '2', '12', '100']

An array index is a String-valued property key that is a canonical numeric String. And a canonical numeric String is a string representation of a number that would be produced by ToString, or the string "-0". So for instance, "012" is not a canonical numeric String but "12" is.

String properties in ascending chronological order of property creation

const object = {
    a: 'a'
};
object.b = 'b';
setTimeOut(() => {
    object.c = 'c';
});
object.d = 'd';
console.log(Object.keys(object));
console.log(Object.getOwnPropertyNames(object));
console.log(Reflect.ownKets(object));
for (const key in object) {
    console.log('key: ', key);
}
// Output: ['a', 'b', 'd']

The above code adds the knowledge point of the event loop. Because setTimeOut is an asynchronous macro task, the c property has not been added to the object when console.log is printed.

Symbol properties in ascending chronological order of property creation

const object = {
    [Symbol('a')]: 'a',
    [Symbol.for('b')]: 'b'
};
Object[Symbol('c')] = 'c';
console.log(Object.keys(object)); // []
console.log(Object.getOwnPropertyNames(object)); // []
console.log(Reflect.ownkeys(object)); // [Symbol(a), Symbol(b), Symbol(c) ]
for (const key in object) {
    console.log('key: ', key);
}
// [ Symbol(a), Symbol(b), Symbol(c) ]
console.log(Object.getOwnPropertySymbols(object));

The Symbol property is the same as the String property, in ascending chronological order of property creation. But the Object.kets, for...in, Object.getOwnPropertyNames methods cannot get the Object's Symbol properties, Reflect.ownKeys and Object.getOwnPropertySymbols can.

Object Properties Order Summary

When an object's property keys are a combination of the above types, the object's non-negative integer keys (enumerable and non-enumerable) are first added to the array in ascending order, and then String keys are added in insertion order. Finally, Symbols kept are added in insertion order.

Thanks for reading the article!!!

KEEP LEARNING AND HAPPY CODING Poster | xxx | Keep Calm-o-Matic