Understanding and Working with Javascript Objects
Tags: javascript, typescript, beginners, webdev
Published: 2020-01-29 11:34:18

**Okay, So what are objects anyway?**

According to MDN :

> In JavaScript, an object is a standalone entity, with properties and type. Compare it with a cup, for example. A cup is an object, with properties.A cup has a color, a design, weight, a material it is made of, etc. In the same way, JavaScript objects can have properties, which define their characteristics.


So, yes javascript Objects in a way are entities to be created when we need these entities to hold some properties and most preferably relate to 
some real-world object [or not based on your requirement].

**How to create an object?**

Well, if you explicitly have never used or created an object, chances are you technically have used an Object.

**whaaa..t? how?**

Here, it comes ... An Array in JavaScript is an Object [One of many things anyway].
Curious about why and what type of an Object?
Here is a stack overflow post that might help:

{% stackoverflow 5048371 %}

Here is a screenshot from the console:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/n1bv2prxa1jk0fb4rhxd.png)


But, as you probably are thinking, yes we cannot create custom properties and define them for an array.

**So, how do we create our own object?**

Well here is a sample code from MDN :

```javascript
var myCar = new Object();
```

Pretty much straight forward right, but since it is JavaScript, we are not actually type checking. [By default, it is of type `any`]

**In typescript:**

For people who want to try it in **typescript** [cause it's pretty much just a superset of javascript], it enforces type checking.

By using the above JavaScript code we will get the below compile time error:
`Property does not exist on type 'Object'`
while setting a property to `myCar`.

So, we need to explicitly mention that it is of type `any` as below:

```javascript
let myCar: any = {};
```
	
If you want an object to be of a specific type then you need to create an interface and then create an object with type as the interface.


**Okay, let's now dig a little deeper into objects and it's properties:**	

Since now we have an object `myCar`, let's set some properties to it:

The below snippet is from MDN:

```javascript
myCar.make = 'Ford';
myCar.model = 'Mustang';
myCar.year = 1969;
```

## Since we now have an object with properties, let's now see what we can do with it:
	
**Display all the keys:**

_Syntax:_ `Object.keys(objectName)`
	
```javascript
console.log(Object.keys(myCar));

(3) ["make", "model", "year"]
	0: "make"
	1: "model"
	2: "year"
	length: 3
	__proto__: Array(0)
```

**Display all the values:**

_Syntax:_ `Object.values(myCar)`

```javascript
console.log(Object.values(myCar));

(3) ["Ford", "Mustang", 1969]
	0: "Ford"
	1: "Mustang"
	2: 1969
	length: 3
	__proto__: Array(0)
```
	
**There is a method called `Object.entries()`:**

This method returns all the Object's own properties as an array in [key : value] format.

```javascript
console.log(Object.entries(myCar));

(3) [Array(2), Array(2), Array(2)] // See, each property is an array.
	0: (2) ["make", "Ford"]
	1: (2) ["model", "Mustang"]
	2: (2) ["year", 1969]
	length: 3
	__proto__: Array(0)
```
**Property Descriptors:**

So, now we know different ways to retrieve the properties of an object. What further helps us is to know that each property has descriptors, which can be accessed by a method `Object.getOwnPropertyDescriptors(Objectname)` 

```javascript
console.log(Object.getOwnPropertyDescriptors(myCar));
	
{make: {…}, model: {…}, year: {…}}
	make: {value: "Ford", writable: true, enumerable: true, configurable: true}
	model: {value: "Mustang", writable: true, enumerable: true, configurable: true}
	year: {value: 1969, writable: true, enumerable: true, configurable: true}
	__proto__: Object
```
	
As we can see from the above snippet that by default these are the properties that javascript sets to an Object. Let's see what these properties mean:
	
- value: Value of the property
- writable: `true` by default which means the property can be changed
- get: a getter function for the property, called when the property is read
- set: a setter function for the property, called when the property is set to a value
- configurable: `true` by default, the property can be removed or changed
- enumerable: `true` if the property is enumerable
	
**Note:**  _Since we did not use any getters or setters in the above code snippet, we cannot see those properties._

Let's now see how we can change a property descriptor:

**To know if an object has a particular property:**

```javascript
console.log(myCar.hasOwnProperty('make')); // return True if available and False otherwise

True
```

**Adding or changing property descriptor:**
	
_Syntax: `Object.defineProperty(Object,property,descriptor)`_
	
```javascript
console.log(myCar.propertyIsConfigurable('make'));

True // By default

Object.defineProperty(myCar , 'make' , { 
  configurable: false
});
```
This method adds property if not present, in this case `make` is present in the Object so we are just changing the descriptor of `make`.

```javascript
console.log(myCar.propertyIsConfigurable('make'));
	
False // Since we change it in the above snippet.
```
  
**Changing writable property descriptor [Read-Only properties]:**

```javascript
Object.defineProperty(myCar , 'make' , {
  writable: false
});
	
console.log(myCar.make = 'SHELBY');

// Runtime error 
ERROR TypeError: Cannot assign to read-only property 'make' of object '[object Object]'
```
	
The above snippet throws an error because we changed writable to false. Hence, it's read-only property.

**Now, let's talk about another method too which is `Object.assign(TargetObject,AsigneeObject)`:**
This method can be used to assign the properties of one object to another.

```javascript
	// Let's make another object
    let myCar2: any = {};
    myCar2.driver = 'KEN MILES';
    myCar2.engine = 'STRAIGHT 6, 3.3L';
    myCar2.specs = '122PS @4000rpm , 257Nm';
	
	// assign myCar2 properties to myCar
	console.log(Object.assign(myCar,myCar2));
	
	{make: "Ford", model: "Mustang", year: 1969, driver: "KEN MILES", engine: "STRAIGHT 6, 3.3L", …}
		driver: "KEN MILES"
		engine: "STRAIGHT 6, 3.3L"
		model: "Mustang"
		specs: "122PS @4000rpm , 257Nm"
		year: 1969
		make: "Ford"
		__proto__: Object
```

As we can see from above that now myCar has the properties of myCar2.

**But, why do we need this method?**

Here is an excellent post on medium that can help you understand the same.

{% medium https://medium.com/@neetishop/why-use-object-assign-582dcdcab6f6 %}


To operate on Objects sometimes we might need an index of the property or we might need to iterate through the property.

**Iterating through Object values. [Can do the same for Keys with `Object.keys`]:**
```javascript
    Object.values(myCar).forEach((element,i) => {
      if(element == 'KEN MILES'){ console.log('INDEX : ',i); }
    });
3 // Index of the property driver.
```
Okay! Now we know how to iterate through Object properties, But what if we need a property that is not to be accessible for iteration but should be available in the Object.

In that case, we can make the property descriptor as non-enumerable as below:

```javascript
    Object.defineProperty(myCar , 'make' , { 
      enumerable: false
    });
	
	console.log(myCar.propertyIsEnumerable('make'));
	
	False // since we changed it above
```
Now, since the property `make` is not enumerable, let's try displaying the properties:

```javascript
console.log(Object.keys(myCar));

(5) ["model", "year", "driver", "engine", "specs"]
	0: "model"
	1: "year"
	2: "driver"
	3: "engine"
	4: "specs"
	length: 5
	__proto__: Array(0)
```
As we can see the property `make` is not accessible.

```javascript
console.log(myCar.hasOwnProperty('make'));

True
```
But as seen above the property is present in the Object.

## Wrapping Up

We now know in javascript and typescript what Objects are , Why do we need them , how to create them and how to operate on them.

Hope this post helps you understand Objects in javascript.

If you find any mistakes , improvements or important topic i have missed do let me know.

Thank You!