Anjan Dutta

Objects in javascript, a beginners guide

Objects in javascript, a beginners guide

Objects in Javascript are collection of properties. An object stores data in the form of key value pair. These are non-primitive type structure, because we can store multiple types (both primitive and non-primitive) data in any object.

While storing data in any object, for our reference, we associate that data to a key name. These keys are known as the object’s property. Object properties can be of any type

For example, a car can have many properties like make, model, year etc. And, we can represent a car or any other entity using an object like below:

var car = {
make: 'Audi',
model: 'A3',
year: 2018
};

How to create objects in Javascript

In Javascript, an object can be created in many ways.

Object literal syntax

var obj = {};

Object constructor syntax

var obj = new Object();

How to define properties in an object

Method 1:

var student = {
name: 'ABC'
}

Method 2:

var fruit = {};
fruit.name = mango;

Method 3:

var animal = {};
animal['species'] = 'Tiger';

Object prototype

In Javascript, objects are closely related to inheritance. When we create an object, along with all of the defined attributes and methods we also get some predefined ones. And that is because of inheritance.

By default, every object is inherited from an Object constructor. If we create an object fro another object like below:

function person(n, a) {
this.name = n;
this.age = a;
}
let p = new person('John', 28);

The immediate parent of object p is the person object. But the root ancestor of p is still an Object.

Now, let’s think of a scenario like this. An object, “person” is the immediate parent of 5 other objects ( p1, p2, p3, p4, p5 ) and after the declaration of each object, we need to update the number of child objects in every other sibling object.

In any other situation, we would have added the property in the parent object person itself. So that when the child objects were inherited, they would have that property since the beginning.

But here we have a condition that only after declaring an object, the number of child objects can be updated. So, what should we do? Should we define the same property for each object explicitly and update them every time? No, we will use the “object.prototype” method for this purpose.

The prototype method adds any property to the base object and that property is immediately available to its child objects.

See the below example:

var person = function(n) {this.name=n};
p1 = new person('p1');
person.prototype.numberOfChild = 1;
p2 = new person('p2');
person.prototype.numberOfChild = 2;
p3 = new person('p3');
person.prototype.numberOfChild = 3;
p4 = new person('p4');
person.prototype.numberOfChild = 4;
p5 = new person('p5');
person.prototype.numberOfChild = 5;
console.log(p1.numberOfChild);
//5

Prototyping is a very smart feature and saves a lot of rewriting effort.

Accessors

Accessors are used to get or set values to any object property. You might ask, isn’t functions serving that purpose already? Yes, those do and so do accessors and along with that, accessors avail a nice layer of abstraction.

Functions require opening and closing brackets for a call but accessors don’t. So it is impossible to say from the outside that the assignment we are making is an assessor call or simply assignment to an object property.

There are two types of accessors, getters and setters.

Getter: A getter is used to access the value of any property and it can be written like below:

get: count() {
.......
.......
// Your logic goes here
.......
.......
}

It’s always good to use a getter whenever we require some pre-formatting before accessing any object property.

Setter: Seters are used to assign value to an object property. Like getters, setters are also used to perform some pre-formatting to the data before assigning it to the object.

We can simply set the value to any of the objects as well, there is no such rule of pre-formatting the data. In this way, we can achieve a level of abstraction.

A setter is written like below:

set: count(num) {
.......
.......
// Your logic goes here
.......
.......
}

A getter never accepts any parameter. The name of a getter and setter should always be the same.

In case if we require a getter or setter in run time, then we use the defineProperty method to create a getter and setter on the fly. We will discuss this property next.

Use of the Object.defineProperty method in Javascript.

Above in this article, you have seen how we can declare an object and its properties. When we declare any property, there are a few rule sets which apply to that property by default. These rule sets are:

  • configurable
  • enumerable
  • writable
  • value

configurable: Defaults to false. Assigning true allows the data type of this property to be changed and this property can be deleted as well.

enumerable: Default value is false. Setting true ensures that this can be enumerated. Or simply said, this property will be visible during for-in and Object.keys.

writable: Defaults to false. Setting this value to true ensures that we can change the value of the object.

value: The data that will be assigned to the property when it is created.

Here is the syntax:

let car = {};
Object.defineProperty(car, 'engineNumber', {
enumerable: false,
configurable: false,
writable: false,
value: 'Z53626'
});

In the above example, we have created an object car. Now we want to declare a property engineNumber which will behave like a private property for this object.

Enumerable property is set to false, hence one can not access the property through for-in or Object.keys methods.

The writable property is also set to false hence we can not change its value. The configurable property is also set to false, hence we can not delete the property or change its type.

At last, the value of the property will be Z53626. We should use this kind of privatization of any property only if there are some common value that is going to be used by all inherited objects.

All of these rules are optional for the defineProperty function. If we don’t declare, then the default value for every rule will be considered.

Below are some of the common problems that we often run into while working with objects.

How to deep clone objects in JavaScript?

let fruitObject = {name: 'Apple', color: 'Red'}
let fruitObj2 = JSON.parse(JSON.stringify(fruitObject));

This is the only way we can deep clone or deep copy an object using native Javascript.

But, this method is not lossless.

For example, if our object contains date objects then after converting to string and back to object will convert those date objects to simple strings.

Hence deep cloning an object using this method is not lossless. A solution is using libraries like lodash which is made for solving such problems.

Here is an example of shallow copying of one object to another object.

let fruitObject = {name: 'Apple', color: 'Red'}
let fruitObj2 = Object.assign({}, fruitObject );

How to remove a property from a JavaScript object?

let fruitObject = { name: 'Apple', color: 'Red' }
delete fruitObject.color;
// { name: 'Apple' }

Using the delete keyword we can delete an object property. The only case if the property is created using defineProperty and configurable is false then delete will not work.

So, make sure to check this before deleting any property.

How to loop through or enumerate a JavaScript object?

let person = {name: 'John', age: 30, address: '18/1, Dover lane' }
for (let key in person) {
console.log(person[key]);
}

This way we can iterate through an object’s properties. Only in case if the property is created using defineProperty and the enumerable is set to false then this method will not access that property.

Check if a key exists in a JavaScript object?

The best way of checking if a key exists in an object is to use the hasOwnProperty() method.

let person = {name: 'John', age: 30, address: '18/1, Dover lane' };
console.log(person.hasOwnProperty('address'));

This property returns true or false based upon the presence of that property.

Another way is to directly check the property by trying to access it.

For example:

let person = {name: 'John', age: 30, address: '18/1, Dover lane' };
if (person.address) {
.......
// Your logic goes here
.......
}

Or like this:

if (person['address']) {
.......
// Your logic goes here
.......
}

The only drawback of the latter method is that we can’t be sure if the object property doesn’t exist or its value is set to null or undefined or false.

How to determine the length of objects in JavaScript?

The optimal way of determining an object’s length in Javascript is to use the Object.keys() method. This method returns an array containing all enumerable properties of an object. Then we will use length property to get the length of that array and it will return the correct length.

See below example:

let person = {name: 'John', age: 30, address: '18/1, Dover lane' };
var size = Object.keys(person).length;

How to merge the properties of two JavaScript objects?

There are two ways we can merge properties of Javascript objects.

First is using Object.assign() method and second is by using a spread operator.

let person = {name: 'John', age: 30, address: '18/1, Dover lane' };
var details = {phone: 1234567890};
let ph = {height: '196cm'}
console.log(Object.assign({},person, details, ph));

This method will merge all three objects in one and will return the merged object. We can use any of the objects in the first place. Then all the other objects will be merged to the first object and that will be returned in the end.

Using spread operator the code would look like below.

let merged = {...person, ...details, ...ph};

How to check for empty objects in JavaScript?

Simply by checking the number of keys, we can determine if an object is empty or not.

The code looks like below:

let sampleObj = {};
if (Object.keys(sampleObj).length === 0) {
.......
// Your logic goes here
.......
}

Detecting an undefined object property

We can detect any undefined object property by type comparison. The code is below:

let person = {name: 'John', age: 30, address: '18/1, Dover lane' };
if ( typeof person.weight === "undefined") {
.......
// Your logic goes here
.......
}

So this is all for now. Hope this article would answer all your object related queries. Thanks for reading.