# Object Destructuring , This, Classes and JSON

## Object Destructuring

Object destructuring is a convenient way of extracting multiple properties from an object and assigning them to variables. It allows you to "unpack" values from objects into distinct variables using a concise syntax.

Suppose we have an Object:

```javascript
const userData = {
  name: "Aquib",
  age: 22,
  isAlive: true,
};
```

And every time when we want to access any property we had to do [`userData.name`](http://userData.name), but there's an easier way to do it for accessing all of the properties that we want to access. Here's an example:

```javascript
const {name: personName, age: personAge, isAlive: personIsAlive} = userData;
console.log(personName); //Aquib
console.log(personAge); //22
console.log(personIsAlive); //true
```

What it has done is that it destructured the object and saved the mentioned specific properties value inside of the custom variable. We selected `name` and then assigned its value inside `personName` variable, and so on. There's even a shorter way to do this -

```javascript
const {name, age, isAlive} = userData;
console.log(name); //Aquib
console.log(age); //22
console.log(isAlive); //true
```

Here the variable names are equal to the properties we want to save in our custom variable. Behind the scene its doing the same operation: `name: personName` but its not assigning it to a different variable name, but actually doing: `name: name` that is why the properties name and our custom variable name are the same while accessing it.

### Nested Object Destructuring

We can create an object that is nested with many objects inside it. For example:

```javascript
const userData = {
  name: "Aquib",
  age: 22,
  isAlive: true,
  address: {
    country: "India",
    state: "Delhi",
    previousAddress: {
      country: "India",
      state: "Bombay"
    }
  }
};
//And so on..
```

We can destructure the nested object like:

```javascript
//Destructuring while making it more readable for you.
const {
  name, 
  age, 
  isAlive, 
  address: {
    country, 
    state, 
    previousAddress: {
      previousCountry, 
      previousState}
    }
  } = userData;

//Else this is what I'm doing - const {name, age, isAlive, address: {country, state, previousAddress: {previousCountry, previousState}}} = userData;

console.log(country); //India
console.log(previousState); //Bombay 

//And so on..
```

### Destructuring in Function Parameters

```javascript
function displayPerson({name, age, address: {state}}) {
    console.log(`Name: ${name}, Age: ${age}, state: ${state}`);
}
displayPerson(userData); //Name: Aquib, Age: 22, state: Delhi
```

Here the function is taking the object as in arguments, but in the parameters we are destructuring them to access its values.

## `this` keyword

The `this` keyword in JavaScript is a special identifier that refers to the context in which a function is executed. Its value depends on how the function is called. Understanding `this` is crucial for writing object-oriented and event-driven JavaScript code.

### `this` in Different Contexts

1. **Global Context**
    

In the global execution context (outside of any function), `this` refers to the global object. In a browser, the global object is `window`.

```javascript
console.log(this); // In a browser, this will log the Window object
```

2. **Function Context**
    

In a regular function, `this` refers to the global object (in non-strict mode). In strict mode, `this` is `undefined`.

```javascript
function showThis() {
  console.log(this);
}

showThis(); // In non-strict mode, this will log the Window object. In strict mode, it will be undefined.
```

3. **Method Context**
    

When a function is called as a method of an object, `this` refers to the object the method is called on.

```javascript
const userData = {
  name: "Aquib",
  age: 22,
  isAlive: true,
  address: {
    country: "India",
    state: "Delhi",
    previousAddress: {
      country: "India",
      state: "Bombay"
    }
  },
  greet: function() {
    console.log(`hello ${this.name} from ${this.address.state} who used to live in ${this.address.previousAddress.state}`);
  }
};

userData.greet(); //hello Aquib from Delhi who used to live in Bombay
```

4. **Constructor Context**
    

When a function is used as a constructor (with the `new` keyword), `this` refers to the newly created instance.

```javascript
function Person(name) {
  this.name = name;
}

const person1 = new Person("Aquib");
console.log(person1.name); // Output: Aquib
```

### Arrow Functions and `this`

Arrow functions do not have their own `this` context. Instead, they inherit `this` from the surrounding non-arrow function or global context. This makes arrow functions particularly useful in situations where you need to preserve the context of `this`.

```javascript
const person = {
  name: "Aquib",
  greet: function() {
    setTimeout(() => {
      console.log(this.name);
    }, 1000);
  }
};

person.greet(); // Output: Aquib
```

<mark>Understanding </mark> `this` <mark>helps in writing more predictable and bug-free JavaScript code, especially when dealing with objects, constructors, and event handlers.</mark>

## Classes

JavaScript classes, introduced in ES6, provide a more familiar and structured way to create objects and handle inheritance. They are essentially syntactical sugar over the existing prototype-based inheritance model.

### Defining a Class

A class is defined using the `class` keyword, followed by the class name, the name should always start with an uppercase. The class body contains methods and properties.

```javascript
class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }

  greet() {
    console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
  }
}

const person1 = new Person("Aquib", 22);
person1.greet(); // Output: Hello, my name is Aquib and I am 22 years old.
```

### Constructor Method

The `constructor` method is a special method for creating and initializing objects created with the `class` keyword. There can only be one special method with the name "constructor" in a class.

### Methods

Methods can be defined directly within the class body. These methods are shared among all instances of the class.

### Inheritance

The `extends` keyword is used to create a subclass that inherits from another class (the superclass). The subclass inherits all the properties and methods from the superclass.

```javascript
class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }

  greet() {
    console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
  }
}

class Student extends Person {
  constructor(name, age, grade) {
    super(name, age); // Call the constructor of the superclass
    this.grade = grade;
  }

  study() {
    console.log(`${this.name} is studying.`);
  }
}

const student1 = new Student("Aquib", 22, 'A');
student1.greet();  // Output: Hello, my name is Aquib and I am 22 years old.
student1.study();  // Output: Aquib is studying.
```

### Super Keyword

The `super` keyword is used to call the constructor and methods of the superclass. In the constructor of the subclass, `super` must be called before accessing `this`.

```javascript
class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }

  greet() {
    console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
  }
}

class Student extends Person {
  constructor(name, age, grade) {
    super(name, age); // Call the constructor of the superclass
    this.grade = grade;
  }

  greet() {
    super.greet(); // Call the greet method of the superclass
    console.log(`I am in grade ${this.grade}.`);
  }
}

const student1 = new Student("Aquib", 22, 'A');
student1.greet();
// Output:
// Hello, my name is Aquib and I am 22 years old.
// I am in grade A.
```

### Static Methods

Static methods are defined using the `static` keyword. They are called on the class itself, not on instances of the class.

```javascript
class MathUtil {
  static add(a, b) {
    return a + b;
  }
}

console.log(MathUtil.add(5, 7)); // Output: 12
```

### Example with Classes and Inheritance

```javascript
class Animal {
  constructor(name) {
    this.name = name;
  }

  speak() {
    console.log(`${this.name} makes a noise.`);
  }
}

class Dog extends Animal {
  constructor(name, breed) {
    super(name); // Call the constructor of the superclass (Animal)
    this.breed = breed;
  }

  speak() {
    super.speak(); // Call the speak method of the superclass
    console.log(`${this.name} barks.`);
  }
}

const dog1 = new Dog("Chhotu", 'German Shepherd');
dog1.speak();
// Output:
// Chhotu makes a noise.
// Chhotu barks.
```

* **Classes**: Introduced in ES6, providing a structured way to define object templates.
    
* **Constructor**: Special method for initializing instances of a class.
    
* **Methods**: Functions defined within a class that operate on instances of the class.
    
* **Inheritance**: Achieved using the `extends` keyword, allowing one class to inherit from another.
    
* **Super Keyword**: Used to call the constructor and methods of a superclass.
    
* **Static Methods**: Methods that are called on the class itself, not on instances.
    

<mark>Classes and inheritance make JavaScript more powerful and expressive, allowing for cleaner and more maintainable code, especially in larger applications.</mark>

## JSON

JSON (JavaScript Object Notation) is a lightweight data-interchange format that's easy for humans to read and write and easy for machines to parse and generate. It is commonly used for transmitting data in web applications between a server and a client.

**JSON is built on two structures:**

1. ### **Object**: An unordered set of name/value pairs.
    
2. **Array**: An ordered collection of values.
    

```javascript
{
  "name": "Aquib",
  "age": 22,
  "country": "India"
}
```

**JSON with Array**

```javascript
[
  { "name": "Aquib", "age": 22 },
  { "name": "Aftab", "age": 23 },
  { "name": "Sunil", "age": 20 }
]
```

### JSON Syntax Rules

* Data is in key/value pairs.
    
* Data is separated by commas.
    
* Curly braces `{}` hold objects.
    
* Square brackets `[]` hold arrays.
    
* Keys are strings and should be enclosed in double quotes `"`.
    
* Values can be strings, numbers, objects, arrays, `true`, `false`, or `null`.
    

### Using JSON in JavaScript

JavaScript provides built-in methods to work with JSON data:

1. `JSON.stringify()`: Converts a JavaScript object into a JSON string.
    

```javascript
const person = {
  name: "Aquib",
  age: 22,
  country: "India"
};

const jsonString = JSON.stringify(person);
console.log(jsonString);
// Output: {"name":"Aquib","age":22,"country":"India"}
```

2. `JSON.parse()`: Parses a JSON string and converts it into a JavaScript object.
    

```javascript
const jsonString = '{"name":"Aquib","age":22,"country":"India"}';

const person = JSON.parse(jsonString);
console.log(person.name); // Output: Aquib
console.log(person.age);  // Output: 22
console.log(person.country); // Output: India
```

<mark>JSON is an essential part of modern web development, enabling efficient data exchange between clients and servers.</mark>
