# Data in JavaScript

## Data Types

### Primitive Data Types

[Primitives](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Data_types) are data types that can only hold 1 discrete piece of data.

There are 7 of them. 2 of them will remain beyond the scope of our course, but here are the 5 to be aware of:

1. `string` - contained inside quotation marks, these are like 'dialogue' in writing. JS just works with the words as they are shown. For example: `"Manav"` or `"Misra"` or even `"23"` - if it's wrapped in `""`, it's a `string`.
2. `number` - JS makes no distinction between integers or floating point numbers; `number`s are just `number`s (unless they are wrapped in `""` 👆🏾).
3. `boolean`- only 2 possibly values: either `true` or `false`. As you can imagine, these are very useful with creating logic statements, 'if this, then that.'
4. `null` - An explicitly assigned value that we **should** use if we just need a *variable* to contain a 'nothing' value. `let x = null;`
5. `undefined` - The absence of any 'real' value, including `null`, but it's still a *primitive data type.* We **should not** deliberately assign this value, but allow JS to use it. For example, if we say `let x;` without assigning a value, JS will assign value of `undefined`.

{% embed url="<https://youtu.be/QUKy3somPnw>" %}
Review of Primitives
{% endembed %}

### Objects

Everything else is an Object. This means it's a composite data type. It can hold several discrete pieces of data, and some of that data may be primitives or it might be nested Objects.

```javascript
/**
  * We create a JS `Object`.
  * It's a useless empty `Object`,
  * but the point is that a JS `Object` is created simply with opening and closing braces.
  */
const myObj = {};

/**
  * Most `Object`s have some data in them held as 🔑 : value pairs.
  * Note that each 🔑 : value pair is separated by a DELIMITER - in this case `:`
  *
  * A DELIMITER simply lets 💻 know where something starts and stops.
  * Here, this is so we can clearly delineate the 🔑 from its corresponding value.
  *
  * All 🔑s MUST BE STRING type.
  * The corresponding value can be of any other data type.
  */
const myObj2 = {
    // 🔑 is ALWAYS STRING!
    'name': 'Manav'
}

// For multiple 🔑:value pairs, we DELIMIT with a `,`
// Note that this is also a JS comment. 👆🏾
// It's a SINGLE-LINE comment style.
const myObj3 = {
  'fname': 'Manav',
  'lname': 'Misra',
  'age': 23,
  'notLyingAboutAge': false
}
```

## Dot Notation and Objects

In large part, programming is about **referencing** data stored in memory for reading, modifying, or completely re-assigning it.

When it comes to *primitive* data types, there is only way to 'modify' that data, it has to be 'thrown out' (yes a 'garbage collector' combs memory for 'unassigned' data and 'cleans it up') and replaced with a new value - there is no modifying of *primitives.* `let x = 3; x = 3 + 1` results in the value `3` being removed and wholly replaced in memory with `4`.

With composite data types, it is perfectly normal to simply modify, or *mutate* data in place. We accomplish this with the use of `.` notation like so: `myObj3.fname` would retrieve the `string` data: `'Manav'`. And, we can modify this by doing something like: `myObj3.fname = "Dave";`

Here, `fname` is a 🔑 that references a *property.* A *property* is akin to a 'noun' in grammar. It describes the *state* of something - it doesn't perform any type of 'action' or 'do' anything, like a 'verb' might.

### Everything in JS is an `object` Except Primitives

\*\*Note: In some of the examples below, I am using [CodePen](https://github.com/savvy-coders/course-materials/tree/b2603fbedf8dd7b72c66d991914582e2a5bf4462/docs/codepen.io) - however, you can just `touch index.js` in your 'practice directory' and try things out there. To run things, you can do: `node index.js` from your command line.

{% embed url="<https://youtu.be/Cd-Eovf2spI>" %}
Object Literals
{% endembed %}

In fact, all of the 'built-in' functionality that we will be using from the 'browser environment' (as opposed to the 'server' - NodeJS), belongs to a special *global object* known as `window`. This *global object* consists of a huge collection of 🔑-value pairs as we have seen 👆🏾. Some of these are *properties,* as we used in our *object literals* ('custom objects) 👆🏾, and others are *methods.* *Methods* perform some type of 'action' and are *invoked* with a set of `()`. In addition, we usually pass in some *arguments* inside of the `()` - these *arguments* provide the *method* with additional information that it might need to do its job. `window.console.log()` will `log` something in the 'console' (in your browser dev tools). However, you won't actually see much at all b/c we need to pass in some *arguments* so that the the `log()` method knows what it's supposed to 'log'. Try: `window.console.log('hello world!')`. Or, assuming you still have an `object` like the one above 'in scope' (means that it's in your JS file where we can still access it in memory), you could do: `window.console.log(myObj3.fname)`.

Now, it would be a real pain to have to type type `window` each and every time to access 'built in' browser-based JS. So, we can omit that part of it and JS still knows what we want. `console.log('hello');` is same as: `window.console.log('hello');`

{% embed url="<https://youtu.be/w6JqXZEb798>" %}
Global Window Object
{% endembed %}

### Nested Objects

It is quite common for `object`s to be nested within one another. Actually, when we do: `window.console.log()`, note that we `console` is another `object` inside of `window`.

```javascript
const nestedObj = {
  name: 'Manav',
  age: 23,
  pets: {
    cats: {
      name: 'Dora',
      isDiabetic: true,
      monthlyCost: 150,
      note: "Does anyone want an old diabetic cat?"
    }
  }
}
```

`console.log(nestedObj.pets.cats.name);` would yield `'Dora'`. Here we are 'chaining' the `.` notation.

{% embed url="<https://youtu.be/NiQXTDqvZDQ>" %}
Nested Objects and Chaining Dot Notation
{% endembed %}
