Defining and Manipulating Classes and Objects in JavaScript
Tags: javascript, oop, tutorial, beginners
Published: 2020-01-03 15:43:01

**Subscribe to my email list now at http://jauyeung.net/subscribe/**

**Follow me on Twitter at https://twitter.com/AuMayeung**

In JavaScript, objects are entities that allow us to encapsulate data, functions, and other objects into one entity that we can access and manipulate. This is another fundamental building block of JavaScript programs.

Objects are used for modeling real-world data. An example would be a bird. We know that it has wings, a head, two legs, and two wings. Also, we know that it can chirp, eat, and fly.

We can model them in JavaScript by using an object. The body parts are the properties of the object, and the actions that it does are the methods.

Methods are functions that are part of the object. Properties are anything denoted with a key-value pair in JavaScript. Methods are special properties. When a property has a function as the value, it’s called a method.

For example, if we model a bird as an object, we can write:

```javascript
const bird = {  
  numWings: 2,  
  numLegs: 2,  
  numHeads: 1,  
  fly(){},  
  chirp(){},  
  eat(){}  
}
```

`fly(){}`, `chirp(){}`, and `eat(){}` are methods and the rest are properties with data as values.

* * *

Creating Objects
================

In JavaScript, we can define objects in three ways. We can either define them as object literals, by using the object constructor method, or by using a class.

Object literal
--------------

Defining objects with object literals is straightforward. We just have to specify the properties and methods of an object directly. For example, we write:

```javascript
const bird = {  
  name: 'Joe',  
  numWings: 2,  
  numLegs: 2,  
  numHeads: 1,  
  fly(){},  
  chirp(){},  
  eat(){}  
}
```

To define an object as an object literal.

If we want to add more properties, we write:

```javascript
bird.sleep = function(){};
```

We can assign anything as values of object properties, so strings, booleans, functions, arrays, and other objects all can be set as properties.

Object constructor
------------------

Equivalently, we can use the object constructor method to define an object. We can write:

```javascript
let bird = new Object();  
bird.name = 'Joe';  
bird.numWings = 2;  
bird.numLegs = 2;  
bird.numHeads = 1;
```

This is a long way to define an object. It’s slower and harder to read than object literals.

Define object instances with classes
------------------------------------

We can also define JavaScript by first defining a class, then using the `new` keyword to create an object, which is an instance of the class.

To do this, we write:

```javascript
class Bird {  
  constructor(name, numWings) {  
    this.name = name;  
    this.numWings = numWings;  
  } 

  logProperties() {  
    console.log(this)  
  }  
}

const bird = new Bird('Joe', 2);  
bird.logProperties();
```

We have the `Bird` class, which is a template for creating an object with the `name` and `numWings` properties and the `getProperties` method.

The `Bird` class has a `constructor` function that lets us pass in values for the properties and set it as properties of the object being created. It also has the `logProperties` function.

`this` is set as the object created as we aren’t using arrow functions as methods.

The object is defined by using the `new` keyword and passing in the data into the `constructor`. Once we’ve defined the object, we can call the methods defined inside it.

In this example, we called `bird.logProperties` to log the value of `this`, which should be `{name: “Joe”, numWings: 2}`.

* * *

Prototypes
==========

In JavaScript, prototypes are templates that let you create other objects. They can also be used for inheritance in JavaScript. So, if we have an `Animal` object defined as:

```javascript
function Animal(){  
  this.name = 'Joe'  
}
```

We can extend it by creating a new object, like so:

```javascript
let bird = animal.prototype;  
bird.fly = function() {};  
bird.chirp = function() {};
```

Then we get the `fly` and `chirp` methods, as well as the `name` property in the `bird` object.

* * *

Defining Functions in an Object
===============================

We can define a function in an object in a few ways.

We can use the `function` keyword or arrow function as usual, but we can also write it with a shorthand for the `function` keyword. For example, if we have a `bird` object and we want to define the `chirp` function, we can write:

```javascript
const bird = {  
 chirp: function(){  
   console.log('chirp', this)  
  }  
}
```

Or use the following shorthand:

```javascript
const bird = {  
 chirp(){  
   console.log('chirp', this)  
  }  
}
```

The two are the same as the `chirp` function will have the `bird` object as the value of `this`.

On the other hand, if you use the arrow function:

```javascript
const bird = {  
 chirp: () => {  
   console.log('chirp', this)  
  }  
}
```

`this` will be logged as the global `window` object, as arrow functions do not change the value of `this` to the object that the function is in.

* * *

Getting and Setting Object Properties
=====================================

After an object is defined, it’s very useful to be able to get and set the properties of an object. There are two ways to get a property of an object. One is to use the dot notation, and another is the square bracket notation.

The dot notation allows us to get properties that have property names that follow the variable naming conventions. That means they start with a letter, underscore, or dollar sign and have no spaces or other special characters.

So, if we have:

```javascript
const bird = {  
  name: 'Joe',  
  numWings: 2,  
  numLegs: 2,  
  numHeads: 1,  
  fly(){},  
  chirp(){},  
  eat(){}  
}
```

Then, we can access the `name` property by writing `bird.name`.

The alternative syntax, which is the square bracket notation, can do the same thing as the dot notation, as well as access properties dynamically.

It also lets us access properties that are defined with names that don’t follow the variable name creation rules. To use the square bracket notation to get object properties, we write: `bird['name']`. We can also write:

```javascript
const prop = 'name';  
bird[prop];
```

This allows us to get properties of an object by passing in variables and string, which is handy for dynamically modifying objects and using objects as dictionaries, as we can traverse the keys and modify them as well as the values.

To set object properties with both notations, we use the assignment operator, like so:

```javascript
bird.name = 'Jane';
```

Or, with square bracket notation, we write:

```javascript
bird['name']= 'Jane';
```

* * *

Get All the Top-Level Properties of an Object
=============================================

All JavaScript has the following functions to get all the top-level properties of an object.

Object.keys
-----------

`Object.keys` gets the top level list of keys of an object and returns an array of them. For example:

```javascript
const a = {foo: 1, bar: 2};  
const length = Object.keys(a).length // 2
```

You can call `find` on the keys array to look for the key, like the following:

```javascript
Object.keys(a).find(k => k == 'foo') // 'foo'
```

Object.getPropertyNames
-----------------------

`Object.getPropertyNames` also gets a list of all top levels of keys of an object and returns them as an array. For example:

```javascript
const a = {foo: 1, bar: 2};  
const length = Object.getOwnPropertyNames(a).length // 2
```

You can call `find` on the keys array to look for the key, like the following:

```javascript
Object.getOwnPropertyNames(a).find(k => k == 'foo') // 'foo'
```

for…in Loop
-----------

There is also a special loop for looping through the keys of an object. You can do the following:

```javascript
const a = {foo: 1, bar: 2};  
let keysCount = 0;  
for (let key in a) {  
    keysCount++;  
}  
console.log(keysCount) // 2
```

* * *

Checking If an Object Property Exists
=====================================

hasOwnProperty
--------------

You can check if an object has a property by calling `hasOwnProperty` of an object. For example:

```javascript
const a = {foo: 1, bar: 2};  
a.hasOwnProperty(key); // true
```

* * *

Deleting Properties of an Object
================================

JavaScript has the `delete` operator to remove a property of an object. If we have:

```javascript
const bird = {  
  name: 'Joe',  
  numWings: 2,  
  numLegs: 2,  
  numHeads: 1,  
  fly(){},  
  chirp(){},  
  eat(){}  
}
```

Then we run `delete bird.name`, then the `bird.name` property will be removed. When you log it, it will log as `undefined`.

* * *

JavaScript Inheritance
======================

In JavaScript, we can create classes where the properties can be included in the properties of a child class.

So, we can have a high-level class that contains the properties that are common to all the child classes, and the child class can have its own special properties that are not in any other classes.

For example, if we have an `Animal` class with the common properties and methods, like `name` and the `eat` method, then the `Bird` class can just inherit the common properties in the `Animal` class. They don’t have to be defined in the `Bird` class again.

We can write the following to do inheritance in JavaScript:

```javascript
class Animal {  
  constructor(name) {  
    this.name = name;  
  }  
  eat() {  
    console.log('eat');  
  }  
}

class Bird extends Animal {  
  constructor(name, numWings) {  
    super(name);  
    this.numWings = numWings;  
  }  
}

const bird = new Bird('Joe', 2);  
console.log(bird.name)  
bird.eat();
```

In the example above, we have the parent class, `Animal`, that has the `eat` method, which all classes that `extends` from `Animal` will have, so they don’t have to define `eat` again.

We have the `Bird` class which extends the `Animal` class. Note that in the `constructor` of the `Bird` class, we have the `super()` function call to call the parent’s class constructor to populate the properties of the parent class in addition to the properties of the child class.

* * *

`this` Keyword
==============

The `this` keyword allows us to access the current object’s properties inside an object unless you’re using arrow functions.

As we can see from the above example, we can get the properties of the instance of the child and the parent class in the object.

* * *

Copying Objects
===============

Copying objects means making a new object reference to an object that has the same contents as the original.

It is used a lot to prevent modifying the original data while you assign a variable to another variable. Because if you assign a variable to a new one, the new one has the same reference as the original object.

There are a few ways to clone objects with JavaScript. Some functions do shallow copying, which means that not all levels of the object are copied, so they may still hold a reference to the original object.

A deep copy copies everything so that nothing references the original object, eliminating any confusion which arises from a shallow copy.

If you assign an object to another variable, it just assigns the reference to the original object, so both variables will point to the original object.

When one of the variables is manipulated, both will be updated. This is not always the desired behavior. To avoid this, you need to copy an object from one variable to another.

Shallow copy
------------

In JavaScript, this is easy to do. To shallow copy an object, we can use `Objec.assign()`, which is built into the latest versions of JavaScript.

This function does a shallow copy, which means it only copies the top level of an object, while the deeper levels remain linked to the original object reference. This may not be desired if there are nested ones in your original object.

Here is an example of how to use `Object.assign`:

```javascript
const a = { foo: {bar: 1 }}  
const b = Object.assign({}, a) // get a clone of a which you can change with out modifying a itself
```

You can also clone an array like this:

```javascript
const a = [1,2,3]  
const b = Object.assign([], a) // get a clone of a which you can change with out modifying a itself
```

Deep copy
---------

To do a deep copy of an object without a library, you can `JSON.stringify` then `JSON.parse`:

```javascript
const a = { foo: {bar: 1, {baz: 2}}  
const b = JSON.parse(JSON.strinfy(a)) // get a clone of a which you can change without modifying a itself
```

This does a deep copy of an object, which means all levels of an object are cloned instead of referencing the original object.

`JSON.parse` and `JSON.stringify` only work with plain objects, which means they cannot have functions and other code that runs.

We can also use object destructuring to shallow clone objects, like so:

```javascript
const a = { foo: {bar: 1}}  
const b = {...a} // get a clone of a which you can change with out modifying a itself
```

Now that we know how to create objects, we can easily store and manipulate data. We can create programs that do non-trivial things with the use of objects and classes.